03 novembre 2009
Contrôle de saisie
En réponse à un p'tit problème de saisie sur Userform, je vous livre ici ma p'tite méthode pour s'assurer que l'utilisateur saisisse des info valides et conformes à l'attente tout en aidant la saisie.
En effet, il est classique de demander la saisie de chiffre et/ou de date à l'utilisateur via un beau Userform que vous avez mis un temps fou à concevoir. Il en reste pas moins que si des garde-fou ne vont pas avec, l'utilisateur pourra saisir n'importe quoi dans un champs devant contenir un nombre (une somme pas exemple) ou une date.
Ainsi la méthode ici exposée, interdit tout simplement la saisie de caractères autre que des chiffres et les signes . (point) et / (slash). Le point sera transformé en virgule si, comme moi, vous avez configuré votre ordi en utilisation clavier français et le slash est utile pour la saisie des dates.
Pour détailler le code, tout d'abord noter la déclaration de 2 constantes "publiques" :
Public Const Touche = "1234567890&é""""'(-è_çà,;:"
Public Const ToucheMaj = "123456789012334567890../"
Ces 2 constantes sont les caractères "autorisés" pour l'une et la traduction pour l'autre. En effet, le deuxième aspect de la question est de faciliter la saisie, pour ceux qui n'ont pas de pavé numérique ,en leur permettant de taper sur la touche des chiffres sans appuyer sur la touche Majuscule en même temps.
Par la suite, le code de votre userform sera agrémenté par les lignes suivantes (pour chaque textbox) :
Private Sub textbox1_keyPress(ByVal KeyAscii As MSForms.ReturnInteger)
If InStr(Touche, Chr(KeyAscii)) = 0 Then KeyAscii = 0 Else _
KeyAscii = Asc(Mid(ToucheMaj, InStr(Touche, Chr(KeyAscii)), 1))
End Sub
En clair : si la touche enfoncée correspond à un signe valide (listé dans la constante "Touche"), on le transforme dans le signe correspondant valide (listé dans la constante "ToucheMaj")
Voilà tout, en quelques lignes de code, votre saisie est sécurisée et facilitée!
tatiak
Téléchargement de : Controle_saisie.zip
31 octobre 2009
Switch MacBook Pro
Depuis un p'tit bout de temps, je lorgnais sur les Mac. Après avoir essayé, avec plus ou moins de bonheur, un certain nombre de Netbook, je suis passé à l'acte. Me voici donc devant un MacBook Pro 13'' tout neuf!
Mes impressions? Il y a du bon ... et du moins bon.
Détaillons.
Il faut dire, tout d'abord, que ce sont des sacrées bonnes machines. Look d'enfer, ordi fin et relativement léger (l'appellation "ultra portable" du MBP vue sur certains sites est à mon sens un peu exagérée), un clavier très confortable et rétro-éclairé (comment s'en passer, maintenant?), une machine silencieuse, un système qui pulse, un système de veille très réactif.
Ce que j'apprécie particulièrement, n'en déplaise à certain, c'est sa compatibilité avec Windows! Ben oui, on ne se refait pas
. Ainsi, via bootcamp, mon MacBook dispose de Snow Léo et de Windows Seven en double boot. Ainsi mes applic PC (professionnelles) ne trouvant pas d'équivalent sous Mac peuvent fonctionner.
Au chapitre des (petites) contrariétés, pour une machine de cette catégorie, je trouve dommage d'avoir fait l'impasse sur certains points. Ainsi le lecteur SDCard ne permet pas à la carte SD son introduction complète! Elle dépasse! Moi qui a l'habitude d'en laisser une pour servir de sauvegarde à certains fichiers sensibles, c'est gênant. D'autre part les ports USB sont mal foutus : il n'y en a que 2, bon passe encore, mais ils sont trop proches l'un de l'autre : dès lors qu'un accessoire usb est un poil large (ma clé 3G par exemple) l'autre port ne peut pas servir, l'utilisation d'un prolongateur s'impose alors, mais encore faut-il penser à l'emmener avec soi!
Pour ce qui est des fonctionnalités spécifiques, autant j'apprécie le rétro-éclairage du clavier (ça, je l'ai déjà dit), autant je suis dubitatif sur ce qui est dit sur le touchpad. Peut être que l'habitude viendra, ou que je ne sais pas me servir de cet accessoire, mais je n'arrive pas à être efficient avec ce truc. Une bonne vielle souris bluetooth me convient cent fois mieux. Et pour finir de râler, un écran mat aurait été le top.
Pour conclure, c'est une machine satisfaisante dans l'ensemble, qui oblige les habitués des machines windows ou linux de revoir certains automatismes (cf configuration des touches du clavier par exemple), mais avec laquelle je devrai faire un bon p'tit bout de chemin!
tatiak
Edit du 22 nov 09 : N'arrivant pas à me faire au clavier (il "manque" des touches!) ni à MacOS (trop de fenêtres dans tous les coins pour une même applic), ni à l'écran (trop brillant qui pique les yeux) je laisse tomber Mac. Le bon point est la facilité de revente, rapide, sans décôte ... Sans regret!
28 juin 2009
"Piloter" Word depuis Excel - 3ème partie
Pour continuer, ce sujet : vos données sont maintenant transcrites dans votre document word, et un peu de mise en forme vous est nécessaire pour les mettre en valeur. Voyons plutôt.
Pour cette démonstration, on suppose que les données à transcrire sont la résultante de plusieurs données Xl.
Votre variable "Transit" sera à 2 dimensions et le texte à écrire pourrait être par exemple :
Texte_à_transcrire= "Article : " & Transit(1, i) & vbcr & Transit(2, i) & vbtab & Transit(3,i)
Vous noterez ici l'intégration de retour chariot "vbcr" pour mettre à la ligne et d'une tabulation "vbtab" pour laquelle il peut être prévu le positionnement préalable d'un taquet dans le document word "de base".
L'intégration de la ligne donnera donc :
With WordDoc.Tables(1)
For i = 1 To Nbdonnées
Texte_à_transcrire= "Article : " & Transit(1, i) & vbcr & Transit(2, i) & vbtab & Transit(3,i)
ligne = .Rows.Count
.Cell(ligne, 1).Range.InsertAfter Texte_à_transcrire
next i
end with
Pour mettre en évidence l'intitulé "Article" contenu dans le texte, on va demander gentillement à "l'application Word" (Dim WordApp As Word.Application) de repérer le mot, de le mettre en gras et de le souligner (par exemple) :
With WordApp.ActiveDocument.Content.Find
.Text = "Article : "
.Forward = False
.Execute
If .Found = True Then
.Parent.Underline = wdUnderlineSingle
.Parent.Bold = True
End If
End With
Pour placer ces lignes dans le code :
With WordDoc.Tables(1)
For i = 1 To Nbdonnées
Texte_à_transcrire= "Article : " & Transit(1, i)
& vbcr & Transit(2, i) & vbtab & Transit(3,i)
ligne = .Rows.Count
.Cell(ligne, 1).Range.InsertAfter Texte_à_transcrire
With WordApp.ActiveDocument.Content.Find
.Text = "Article : "
.Forward = False
.Execute
If .Found = True Then
.Parent.Underline = wdUnderlineSingle
.Parent.Bold = True
End If
End With
next i
end with
Voilà, tout, il est possible, et même certain, que ces lignes peuvent être améliorées, je suis preneur de toutes suggestions. Ce que je peux vous dire, c'est que ça "fait le job" dans une applic utilisée quotidiennement dans mon boulot.
Merci par avance des commentaires que vous me laisserez,
tatiak
"Piloter" Word depuis Excel - 2ème partie
Pour continuer les explications du 14 juin, et pour aller plus loin, voici comment compléter un tableau dans un document Word depuis Excel.
L'idée ici est de mettre en page des données Xl en adaptant la taille du tableau word avec la quantité de données à insérer.
Nous avons donc créé un document word comme indiqué précédemment dans lequel figure un tableau. Je vous suggère de faire un tableau ne contenant qu'une seule ligne qui sera vide (pour cet exemple un tableau d'une seule colonne sera utilisé, le principe pour plusieurs est le même)
Dans un premier temps, les données Xl seront lues et placées dans une variable de "transit" (ici pour l'exemple les données sont dans la colonne A):
Dim Transit() as string, Nbdonnées as integer, i as integer
Nbdonnées = Feuil1.Range("A65000").End(xlUp).Row
Redim Transit(Nbdonnées) ' pour dimensionner dynamiquement la variable
For i = 1 To Nbdonnées
Transit(i)= Feuil1.cells(i,1).value
next i
Après ouverture du fichier word (comme indiqué dans le post précédent), on place la première données dans le tableau (ici table(1)), puis on ajoute éventuellement une nouvelle ligne dans le tableau pour pouvoir placer la données suivante :
With WordDoc.Tables(1)
For i = 1 to Nbdonnées
ligne = .row.count
.Cell(ligne, 1).Range.InsertAfter Transit(i)
If i < Nbdonnées Then .Rows.Add
Next i
end with
Et voilà à la suite, il convient de fermer proprement le fichier Word comme indiqué précedemment et votre document est mis à jour!
tatiak
14 juin 2009
"Piloter" Word depuis Excel - 1ère partie
Quoi de plus confortable de pouvoir générer un document mis en page avec Word depuis une base de données Excel! En effet, de cette manière, on profite entièrement de la puissance d'un vrai logiciel de traitement de texte, et on peut aller plus loin qu'une fusion de base, pour "mettre en valeur" nos données Excel.
Pour répondre à des demandes multiples, je vous donne ma p'tite méthodologie, en expliquant ici l'insertion de données à l'emplacement d'un signet (pour le nom du client par exemple) et dans un tableau (pour les articles commandés par exemple)
Donc, pour ce type de besoin, je crée un document word qui me sert de modèle (ici dans l'exemple ModèleDocument.doc, situé dans un sous répertoire Document), si besoin avec signet (nommé ici "SIGNET_A CREER_DANS_DOCUMENT_WORD") et tableau (ici un seul tableau donc wordDoc.tables(1)).
Dans un premier temps, la macro crée une instance Word et ouvre le modèle :
Sub Vers_Word()
Dim NDF As String, NDF2 As String
Dim WordApp As Word.Application
Dim WordDoc As Word.Document
NDF = ActiveWorkbook.Path & "\ModèleDocument.doc"
NDF2 = ActiveWorkbook.Path & "\Document" & Sheets("Feuil1").Range("A1").text & ".doc"
On Error Resume Next
Set WordApp = CreateObject("Word.Application")
Set WordDoc = WordApp.Documents.Open(NDF, ReadOnly:=False)
A noter : on prévoit dès le début de sauvegarder le document avec
un nom comportant ici le contenu de la cellule A1 (un nom de client par
exemple) pour ne pas écraser le modèle.
Puis il convient d'écrire les données :
* pour écrire à partir du signet "SIGNET_A CREER_DANS_DOCUMENT_WORD" (ici le contenu de la cellule A2 :
With WordApp
.Visible = False
.Selection.Goto What:=wdGoToBookmark, Name:="SIGNET_A CREER_DANS_DOCUMENT_WORD"
.Selection.TypeText Text:= Sheets("Feuil1").Range("A2").Value
* pour écrire dans le tableau 1 ligne 1, colonne 2 (ici le contenu de la cellule A3) :
With WordDoc.Tables(1)
.Cell(1, 2).Range.InsertAfter Sheets("Feuil1").Range("A3").Value
End With
Ne pas oublier de sauvegarder le document sous le nom défini précédemment :
WordDoc.Application.ActiveDocument.SaveAs NDF2
Enfin, il convient de fermer le tout proprement et de libérer la mémoire en mettant les variables à zéro :
WordApp.Application.Quit
Set WordDoc = Nothing
Set WordApp = Nothing
Ce qui donne au global :
Sub Vers_Word()
Dim NDF As String, NDF2 As String
Dim WordApp As Word.Application
Dim WordDoc As Word.Document
NDF = ActiveWorkbook.Path & "\ModèleDocument.doc"
NDF2 = ActiveWorkbook.Path & "\Document" & Sheets("Feuil1").Range("A1").text & ".doc"
On Error Resume Next
Set WordApp = CreateObject("Word.Application")
Set WordDoc = WordApp.Documents.Open(NDF, ReadOnly:=False)
With WordApp
.Visible = False
.Selection.Goto What:=wdGoToBookmark, Name:="SIGNET_A CREER_DANS_DOCUMENT_WORD"
.Selection.TypeText Text:= Sheets("Feuil1").Range("A2").Value
With WordDoc.Tables(1)
.Cell(1, 2).Range.InsertAfter Sheets("Feuil1").Range("A3").Value
End With
End With
WordDoc.Application.ActiveDocument.SaveAs NDF2
WordApp.Application.Quit
Set WordDoc = Nothing
Set WordApp = Nothing
End Sub
La référence MS Word machin est activée bien sûr!
Et voili!
tatiak
PS : Dans le post à venir, je vous expliquerais comment faire de la mise en forme du texte contenu dans une case d'un tableau (toujours depuis XL dans un document Word), dès son intégration.
PS2 : pour JC, il s'agit bien ici de VBA Excel!
29 mars 2009
Fichiers .mod
Certains appareils de capture vidéo génèrent des fichiers au format .mod. Ces fichiers sont en fait des fichiers mpeg, mais dont l'extension est "personnalisée" par le constructeur de l'appareil pour faire croire à un format propriétaire.
Lors du transfert de ce type de fichier vers son PC, l'exercice consiste à simplement modifier l'extension .mod en .mpg
Plutôt que de faire cette modification à la main pour l'ensemble des fichiers à traiter, rien de tel que quelques lignes de VBS pour automatiser ces opérations. (Attention ceci n'est pas du VBA, mais du VBS ;)).
Option Explicit
Const WINDOW_HANDLE = 0
Const NO_OPTIONS = 0
Dim fso, Chemin, Fichier, FichierItem
Dim NomF, NouveauNomF
Chemin = SelectionDossier("Sélectionner le dossier contenant les fichiers à convertir ","" )
if not Chemin = "ANNULATION" then
on error resume next
beep
Set fso = CreateObject("Scripting.FileSystemObject")
For Each Fichier In fso.GetFolder(Chemin).Files
Set FichierItem = fso.GetFile(Fichier)
NomF = Fichier.name
NouveaunomF = Replace(NomF, ".mod", ".mpg")
fso.MoveFile Chemin & NomF , Chemin & NouveauNomF
next
end if
Function SelectionDossier (message,directory)
Dim objShell, objFolder, objFolderItem
Set objShell = CreateObject("Shell.Application" )
Set objFolder = objShell.BrowseForFolder (WINDOW_HANDLE, message , NO_OPTIONS, directory)
On Error Resume Next
Set objFolderItem = objFolder.Self
If Err <> 0 Then
SelectionDossier = "ANNULATION"
Else
SelectionDossier = objFolderItem.Path & "\"
end if
On Error GoTo 0
set objShell = nothing
set objFolder = nothing
set objFolderItem = nothing
End Function
Télécharger le fichier : ConversionMPG.zip
:) tatiak
28 mars 2009
Danses Noires / Blanche Amérique

CND, 1, rue Victor HUGO 93500 Pantin
Big Brother
24 janvier 2009
EEE Pc T91
Voici une vidéo de l'interface du futur nouveau Eee Pc T91, à écran tactile.
Je suis bluffé!Je sens que je vais encore craquer sur ce Eee qui devrait être disponible sur le premier semestre 2009!
29 novembre 2008
Synchronisation Dossiers et Sous-Dossier - VBScript
Avant propos : Et non ce n'est pas du VBA pour Excel, mais du VBS qui "marche tout seul" ;)
Pour faire suite à mon post précédent, et pour aller plus loin dans les contraintes, voici la version suivante du script de synchronisation. En effet, le point "faible" du script précédent est qu'il ne traitait pas les sous-répertoires du dossier choisi.
Voici donc un outil plus complet, capable de traiter les fichiers, les sous répertoires et les fichiers des sous répertoires d'un dossier quelconque à choisir.
Téléchargement de : Synchronisation_DOSSIERS.zip
Dans le code, vous remarquerez 2 fonctions qui sont le "moteur" de l'outil. Une première liste les fichiers du dossier "source" :
Function ListerDossier(Chemin)
Dim Fso, SousRepertoire, SousFichier, SousFichierItem
if right(Chemin, 1) <> "\" then Chemin = Chemin & "\"
On Error Resume Next
Set Fso = CreateObject("Scripting.FileSystemObject")
For Each SousRepertoire In Fso.GetFolder(Chemin).SubFolders
ListerDossier SousRepertoire.Path
Next
For Each SousFichier In Fso.GetFolder(Chemin).Files
Set SousFichierItem = Fso.GetFile(SousFichier)
nbfichiers = nbfichiers +1
ReDim Preserve Tableau(3, nbfichiers)
Tableau(1, nbfichiers) = replace (Chemin, Chemin1 , "")
Tableau(2, nbfichiers) = SousFichier.Name
Tableau(3, nbfichiers) = SousFichierItem.DateLastModified
next
End Function
L'autre fonction liste le contenu du dossier "cible" et effectue le traitement de copie et de mise à jour du contenu de la "source" et de la "cible" :
Function ComparerFichier(Chemin)
Dim Fso, SousRepertoire, SousFichier, SousFichierItem
if right(Chemin, 1) <> "\" then Chemin = Chemin & "\"
On Error Resume Next
Set Fso = CreateObject("Scripting.FileSystemObject")
For Each SousRepertoire In Fso.GetFolder(Chemin).SubFolders
if not Fso.FolderExists(Chemin1 & sousrepertoire.name) then Fso.CreateFolder (Chemin1 & sousrepertoire.name)
ComparerFichier SousRepertoire.Path
Next
for i = 1 to nbfichiers
For Each SousFichier In Fso.GetFolder(Chemin).Files
Set SousFichierItem = Fso.GetFile(SousFichier)
if not Fso.FileExists(Chemin1 & replace(Chemin, Chemin2, "") & SousFichier.name) then
Fso.CopyFile Chemin & SousFichier.Name , Chemin1 & replace(Chemin, Chemin2, ""), true
end if
if tableau(1,i) = replace(Chemin, Chemin2, "") and tableau(2,i) = SousFichier.name then
If CDate(tableau(3,i)) > CDate(SousFichierItem.DateLastModified) Then
Fso.CopyFile Chemin1 & replace(Chemin, Chemin2, "") & tableau(2,i) , Chemin2 & replace(Chemin, Chemin2, ""), true
else
Fso.CopyFile Chemin2 & replace(Chemin, Chemin2, "") & tableau(2,i) , Chemin1 & tableau(1,i) , true
end if
end if
next
if not Fso.FileExists(Chemin2 & tableau(1,i) & tableau(2,i)) then
Fso.CopyFile Chemin1 & tableau(1,i) & tableau(2,i) , Chemin2 & tableau(1,i), true
end if
next
End Function
Voilà tout, n'hésitez pas à me faire part de vos remarques si vous trouvez un bug!
:) tatiak




