Macro pour lancer une impression

  • Auteur de la discussion GTmacrodeb
  • Date de début

GTmacrodeb

Expert
Bonjour à toute la communauté,

Voici les données de mon "problème" :

J'ai actuellement un document Excel avec différentes feuilles, dont une liste différents modes opératoires. Devant chaque mode opératoire, j'ai une cellule dans laquelle je viens mettre un "X" pour le sélectionner.

Je souhaiterais créer une macro qui permette de lancer l'impression des modes opératoires lorsqu'ils sont sélectionnés.

Les modes opératoires sont actuellement tous stockés dans un dossier et chaque mode opératoire est au format word. La manipulation est-elle possible de cette manière ?

Sinon, j'avais pour idée de convertir chaque mode opératoire dans une feuille Excel que j'afficherai ou non en fonction de la sélection. Je ne sais pas comment convertir ces fiches .doc en .xls.

Pourriez-vous m'indiquer quelle démarche vous semble la plus simple et efficace ?

Merci par avance pour votre aide.

GTmacrodeb
 

zeb

Modérateur
Salut,

Je ne conçois pas qu'on veuille et même qu'on puisse convertir des documents texte (.doc) en feuilles de calcul (.xls). Aussi, pensé-je que la première solution est à préférer, d'autant qu'elle ne me semble pas compliquée à implémenter.
 

GTmacrodeb

Expert
Merci pour tes précisions.

Je suis partant pour la 1ère solution par contre je ne sais pas quelle fonction utilisée pour indiquer les documents correspondants en fonction des cellules sélectionnées...

J'ai bien utilisé l'enregistreur de Macro Excel mais il n'enregistre pas les actions que j'ai effectuées pour ouvrir le fichier Word. :??:

Serait-il possible d'orienter mes recherches ?
 

zeb

Modérateur
Ah, un adepte de l'enregistreur de macro :)

Et bien deux solutions :

■ Utilise-le aussi dans Word pour savoir comment imprimer. Et je t'aiderai à mixer la macro Excel et la macro Word à partir de ce que tu publieras.

■ Pas la peine d'ouvrir Word pour imprimer : cf. ShellExecute() (API Windows).
 

GTmacrodeb

Expert
Bonjour,

Dans un premier temps, j'essaye de réaliser ce code pour un mode opératoire précis pour voir comment il s'organise.

Voici le code que je peux proposer :

[cpp]
Option Explicit

Sub ImpressionMO()

Dim ws_annexe1 As Worksheet

Set ws_annexe1 = Worksheets("Fiche00")

If ws_annexe1.Range("C7") <> "" Then

ShellExecute(Handle,"Print","\Mgcesrv01\chantiers\DOSSIER COMMUN\PPSPS MGCE\PPSPS\Fiche Ouvrages\MO 0.00 Les Bonnes Pratiques du Chantier.doc",nil,nil,SW_SHOWDEFAULT)

End If

Next

End Sub[/cpp]

Le souci c'est qu'avec ce code, j'ai un message d'erreur ligne11 "Erreur de compilation : erreur de syntaxe".

Merci d'avance pour votre aide.

 

zeb

Modérateur
Salut,

Bien sûr que tu as une erreur de syntaxe. Tu colles la syntaxe C et tu copies directement en VB. Ça ne fonctionne pas comme ça.
D'abord, VB ne connaît pas les fonctions Windows. Il faut les lui apprendre. Pour cela, on utilise un clause Declare :
Code:
Declare Function ShellExecute _
            Lib "shell32.dll" _
          Alias "ShellExecuteA" (ByVal hwnd As Long, _
                                 ByVal lpOperation As String, _
                                 ByVal lpFile As String, _
                                 ByVal lpParameters As String, _
                                 ByVal lpDirectory As String, _
                                 ByVal nShowCmd As Long) As Long
De la même façon, les constantes utilisées par la fonction n'existent pas non plus. Il faut soit les créer, soit utiliser directement leur valeur.
L'API utilise toutes ces constantes : ERROR_BAD_FORMAT, ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND, SE_ERR_ACCESSDENIED, SE_ERR_ASSOCINCOMPLETE, SE_ERR_DDEBUSY, SE_ERR_DDEFAIL, SE_ERR_DDETIMEOUT, SE_ERR_DLLNOTFOUND, SE_ERR_FNF, SE_ERR_NOASSOC, SE_ERR_OOM, SE_ERR_PNF, SE_ERR_SHARE, SW_HIDE, SW_MAXIMIZE, SW_MINIMIZE, SW_RESTORE, SW_SHOW, SW_SHOWDEFAULT, SW_SHOWMAXIMIZED, SW_SHOWMINIMIZED, SW_SHOWMINNOACTIVE, SW_SHOWNA, SW_SHOWNOACTIVATE, SW_SHOWNORMAL.
Bon, on définira juste SW_SHOWDEFAULT par principe.
Code:
Const SW_SHOWDEFAULT = 10

Et ce handle, à quoi correspond-il ? En général, il s'agit du handle de la fenêtre de l'application, récupérable grâce à la propriété hWnd de l'objet.
En fait, on s'en passera. Ca donne, à l'appel :
Code:
ShellExecute 0, "Print", "chemin\mon fichier.doc", vbNullString, vbNullString, SW_SHOWDEFAULT
Ou si tu veux récupérer le code d'erreur :

Code:
Dim rc As Long
rc = ShellExecute(0, "Print", "chemin\mon fichier.doc", vbNullString, vbNullString, SW_SHOWDEFAULT)
If rc > 32 Then MsgBox "Doument imprimé"
 

GTmacrodeb

Expert
Bonjour,

Je dois avouer que je suis un peu perdu...

J'ai bien essayé de copier ce code en l'intégrant à la macro précédente mais il m'indique un message d'erreur "Erreur de compilation : Seuls des commentaires peuvent apparaître après End Sub, End Function, ou End Property". Ce message concerne la clause Declare.

J'ai essayé la manip en intégrant ce code dans une autre macro sur le même module et j'ai le même message d'erreur.

Dernier point, j'ai bien consulté l'aide d'Excel mais je ne comprends pas à quoi sert la condition "If rc > 32 Then MsgBox "Document imprimé"". Comment est défini ce 32 ? Est-ce normal qu'on ne mette pas de Enf If puis Next ?

Désolé pour mes lacunes... [:_tom_:5]
 

zeb

Modérateur
Alors un peu de boulot pour toi, avant d'aller plus avant.

Demande l'aide sur le mot Declare. Première phrase, où l'on parle de niveau. Si tu n'y comprends rien, dis-le moi.

Demande l'aide sur le mot If. Rubrique Syntaxe. C'est comme ça, il y a plusieurs syntaxes. C'est moche, mais VB, c'est avant tout du BASIC, un des plus vieux langages de 3ème génération.

Quel Next ?

Relis l'aide sur ShellExecute ( ), rubrique Return Value.

--------------------

Je viens de te faire faire un RTFM :lol: :lol: :lol:
Dès que tu auras moins d'interrogations, on continuera ;)
 

GTmacrodeb

Expert
Alors merci pour ces précisions !

Désolé pour la confusion entre le If et le Next...

J'ai donc repris la macro et elle fonctionne pour le MO0.

La voici :


[cpp]
Option Explicit

Declare Function ShellExecute _
Lib "shell32.dll" _
Alias "ShellExecuteA" (ByVal hwnd As Long, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As Long

Sub Impression()

Dim ws_annexe1 As Worksheet
Dim rc As Long

Const SW_SHOWDEFAULT = 10

Set ws_annexe1 = Worksheets("Fiche 00")

If ws_annexe1.Range("C7") <> "" Then

rc = ShellExecute(0, "Print", "\\Adresse_du_document.doc", vbNullString, vbNullString, SW_SHOWDEFAULT)
If rc > 32 Then MsgBox "Document imprimé"

End If

End Sub
[/cpp]

Maintenant d'autres questions :

Mes cases à cocher se situent en colonne C et J et les noms des fiches correspondantes respectivement en colonne F et M.
Les noms des documents précisés sur la feuille Excel ne sont pas exactement les mêmes que les noms des fichiers mais ils se ressemblent beaucoup (Ex : sur Excel "Installation" et le nom du fichier correspondant "MO 4.30 Installation.doc").

Existe-t-il un moyen pour que la macro parvienne :
- à identifier les noms des documents (en F ou M) pour lesquels on à placé une X (en C ou J) sans que ces documents aient exactement le même nom ?
- à reconnaître le fichier .doc correspondant sans qu'il n'ait nécessairement le même non ?

Ou peut-être vaut-il mieux que je précise pour chaque cellule à quel document elle fait référence ?

Dernière question :
Existe-t-il un moyen pour paramétrer l'impression ? (Recto-Verso, Couleur, Autre imprimante que celle définie par défaut)

Merci encore.
 

zeb

Modérateur
Pas mal. Bon, maintenant, la constante SW_SHOWDEFAULT est intrinsèquement liée à l'API dont les déclarations se font à l'extérieur des fonctions.
Je t'invite donc à ranger la déclaration de cette constante au même endroit que celle de la fonction. (pinaillage)

Je t'en conjure, respecte la sacro-sainte loi de l' - louée soit-elle.
Ce n'est pas une demande de ma part, c'est une injonction au nom du Dieu Informatique. (mystique)

VBA ne peut pas deviner que deux chaînes de caractères se ressemblent. C'est d'ailleurs très difficile en informatique.
Cela dit, voici quelques éléments de réflexion :
■ s'affranchir des différences de casse (majuscules/minuscule)
■ s'affranchir des problèmes d'accents
■ se baser sur un dénominateur commun à fixer

Admettons que nous aillons installation dans la cellule M1.
Si fname est le nom du fichier, le test suivant est vrai pour le nom de fichier MO 4.30 Installation.doc :
Code:
If UCase(fname) Like UCase("*" & Range("M1").Text & "*.doc") Then ..

Ou peut-être vaut-il mieux que je précise pour chaque cellule à quel document elle fait référence ?
Voilà une idée, toute bête, toute simple. :) Mais qu'est-ce qu'elle est bonne !!!!

Existe-t-il un moyen pour ..
T'as demandé à l'enregistreur de macro, juste pour voir ?
Fais une impression Recto. Fais une impression Verso. Compare. Déduis... :o

(Y'a juste que tu n'auras pas sauvé la planète en gâchant deux feuilles de papier)
 

GTmacrodeb

Expert
Je viens de faire correspondre chaque cellule aux documents souhaités. Cela mérite déjà des remerciements.

Par contre lorsque j'ai plusieurs documents à imprimer, il m'affiche la fenêtre MsgBox pour chaque document imprimé. Est-il possible d'avoir ce message uniquement à la fin de toutes les impressions ?

Merci d'avance.
 

zeb

Modérateur
Tu veux dire le "Document imprimé" !!!!!?
Ben vire-le.

Je t'ai mis un exemple pour savoir si tout c'est bien passé pour 1.
A toi de voir comment faire pour faire un compte rendu global, avec le nombre de fichiers total, le nombre d'impressions réussies, le nombre d'échecs.

----------------------------------

Euh, je crois que si tu veux passer des paramètres d'impression (recto-verso, changement d'imprimante, couleur/b&w, etc.), la méthode ShellExecute(..,"Print",....) n'est pas la bonne :/



Il faut revenir à l'impression par Word. Ça n'est pas plus compliqué, au contraire, mais il faut tout refaire. Pas grave, l'enregistreur de macro va beaucoup nous aider.

J'ai déjà de bonnes idées. Soumets-moi les tiennes, qu'on partage ;)
 

GTmacrodeb

Expert
Avant de confirmer si je me contente de la solution précédente ou si je me lance dans une macro sous word, pourrais-tu m'indiquer si une de ces 2 solutions (ou peut-être les 2) est envisageable sans que l'on ait la fenêtre de Word qui s'ouvre avec le document correspondant ? Ou tout du moins la fenêtre qui s'affiche à l'écran.

J'ai essayé de le paramétrer dans la macro en remplaçant le paramètre SW_SHOWDEFAULT par un SW_HIDE mais je n'y suis pas parvenu. J'ai déclaré la Constante de cette manière :
[cpp]Const SW_HIDE = 0[/cpp]

Merci d'avance.

 

zeb

Modérateur
Partons sur l'idée d'une macro Word.
Avec l'aide de l'enregistreur, tu me fais une macro VBA/Word pour imprimer un document recto-verso en couleurs et paysage, et je te montre comment en faire une macro VBA/Excel qui n'ouvre pas de fenêtre Word et qui t'imprime tous les documents que tu veux.

Sympa le deal ? ;)
 

GTmacrodeb

Expert
Alors voici la macro que j'ai à te proposer (réalisée avec l'enregistreur):

[cpp]Option Explicit
Sub Macro1()

ActivePrinter = "\\192.168.4.6\Ricoh Couleur"
Application.PrintOut FileName:="", Range:=wdPrintRangeOfPages, Item:= _
wdPrintDocumentContent, Copies:=1, PageType:= _
wdPrintAllPages, ManualDuplexPrint:=False, Collate:=True, Background:= _
True, PrintToFile:=False, PrintZoomColumn:=0, PrintZoomRow:=0, _
PrintZoomPaperWidth:=0, PrintZoomPaperHeight:=0

End Sub[/cpp]

Déroulé de la macro :
- Je sélectionne l'imprimante couleur qui n'est pas celle par défaut,
- J'ai demandé une impression recto-verso.

La feuille est par défaut en paysage, j'ai juste modifié le sens de rotation (sur la gauche au lieu de par le haut).

Merci encore pour tes précieux conseils.
 

zeb

Modérateur
Bon alors on va surtout pas commencer à s'énerver sur les paramètres spécifiques de ton imprimante, genre le recto-verso par exemple. C'est un peu . Mais on pourra y revenir si tu veux.

En attendant, concentrons-nous sur ton code.

Moi, j'observe une propriété - ActivePrinter - et une méthode - PrintOut(). Et je demande l'aide de VBA/Word.
Concernant ActivePrinter, c'est trivial. Quant à PrintOut(), ce qui est intéressant, c'est que c'est aussi une méthode de l'objet Document.

Alors voilà ce que je propose : on va ouvrir un Word, y charger uns à uns tous nos documents, les imprimer au fur et à mesure, puis fermer Word, tout ça à partir d'Excel.
On y va ?

Code:
Dim appWord As Object ' // Par défaut, Excel ne connaît pas les objets Word.
Dim docWord As Object ' // Restons vague ~~~~

' // Instancier Word
Set appWord = CreateObject("Word.Application")
appWord.ActivePrinter = "ton imprimante"

For Each nom_du_fichier In [Il faut ici parcourir les noms de fichiers que tu veux imprimer !]
    Set docWord = appWord.Documents.Open(nom_du_fichier, ReadOnly:=True)
    docWord.PrintOut ' // <-- Impression
    docWord.Close SaveChanges:=False
Next

appWord.Quit
 

GTmacrodeb

Expert
Avant de me lancer dans la rédaction, j'ai quelques soucis de compréhension sur certains termes. :??:

Qu'entends-tu par "charger uns à uns tous nos documents" ? Il doit tous les charger ou uniquement ceux sélectionnés ?

2e point : dans le code de la macro tu me parles de "parcourir les noms des fichiers". Cela signifie-t-il que je dois le compéter pour nom de chaque fichier ? Ou peut-être veux-tu dire qu'il faut que je copie le chemin pour chaque fichier ?

Peut-être que je veux aller plus vite que la musique en souhaitant imprimer uniquement les documents sélectionnées...

Merci pour tes précisions.
 

GTmacrodeb

Expert
Voici le code que j'ai adapté pour un seul fichier

[cpp]Option Explicit

Sub Impression2()

Dim appWord As Object ' // Par défaut, Excel ne connaît pas les objets Word.
Dim docWord As Object ' // Restons vague ~~~~
Dim ws_annexe1 As Worksheet
Dim Cell As Range

Set appWord = CreateObject("Word.Application")
appWord.ActivePrinter = "\\192.168.4.6\Ricoh Couleur"
Set ws_annexe1 = Worksheets("Fiche 00")

For Each Cell In ws_annexe1.Range("C7") '[Il faut ici parcourir les noms de fichiers que tu veux imprimer !]
If Cell <> "" Then
Set docWord = appWord.Documents.Open("\\chemin_du_fichier.doc", ReadOnly:=True)
docWord.PrintOut ' // <-- Impression
docWord.Close SaveChanges:=False

End If

Next

appWord.Close

End Sub[/cpp]

Dans l'état actuel des choses, il m'imprime le document en couleur sur l'imprimante choisie.

Par contre, j'ai un débogage sur la ligne24 "Erreur d'exécution '438' : Propriété ou méthode non gérée par cet objet".

Pour la suite, je dois réitérer cette procédure pour chaque document ?

Merci.
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 135
Messages
6 718 106
Membres
1 586 397
Dernier membre
Chachabidou
Partager cette page
Haut