|
| Iniciado por TheCout, 30,abr. 2020 10:01 - 4 respuestas |
| |
| | | |
|
| |
Miembro registrado 104 mensajes |
|
| Publicado el 30,abril 2020 - 10:01 |
Bonjour,
Je suis confronté à un problème parfaitement reproductible.
Je veux manipuler un fichier Excel avec Automation et que l'utilisateur voit le résultat.
Donc j'ai fait dans un premier temps:
v_obj_xls est un objet automation "Excel.Application" v_obj_xls>>Visible = Vrai
Le problème avec çà est que Excel reste derrière la fenêtre de mon application. Il faut que l'utilisateur l'active.
Du coup, j'ai fait plutôt ceci:
LanceAppli(...
v_obj_xls est un objet automation dynamique
ChronoDébut() BOUCLE v_obj_xls = ObjetActif("Excel.Application") SI v_obj_xls <> Null SORTIR SINON v_dur = ChronoValeur() SI v_dur..EnSecondes > 30 Erreur("Excel inaccessible") RETOUR FIN FIN FIN
Le problème, c'est que ObjetActif renvoie toujours null. Il faut que je remette mon appli avant-plan, quitte ensuite à remettre Excel en avant plan à nouveau et là ObjetActif fonctionne.
Est-ce que certains ont déjà rencontré ce problème ? Avec Word, on n'a pas ce problème. |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 948 mensajes |
|
| Publicado el 01,mayo 2020 - 20:19 |
Bonjour J'ai trouvé cette méthode mais c'est un petit lourd...Il y a surement mieux
WindowsFound est un booléen WinPID est un entier système ExcelFileName, CompleteExcelFileName, ListeDesFenetres, sLigne est une chaîne xl est un objet automation dynamique
ExcelFileName = "tests.xlsx" CompleteExcelFileName = ComplèteRep(fRepExe()) + ExcelFileName IF NOT fFichierExiste(ExcelFileName) THEN Erreur("Fichier Excel inconnu !") RETOUR END
xl = allouer un objet automation "Excel.Application" IF xl = Null THEN Erreur("Erreur 'Excel.application' n'est pas installé sur ce poste !") RETOUR END xl>>Visible = True xl>>WorkBooks>>Open(CompleteExcelFileName) Multitâche(0) ListeDesFenetres = EnumWindows() IF ListeDesFenetres = "" THEN Erreur("Impossible de lister les fenêtres !") xl>>ActiveWorkbook>>Close() xl>>Quit() RETOUR END
WindowsFound = False FOR ALL STRING sLigne OF ListeDesFenetres SEPARATED by CRLF IF ChaîneOccurrence(sLigne, ExcelFileName) > 0 THEN WindowsFound = True; SORTIR END
IF NOT WindowsFound THEN Erreur("Fenêtre non trouvée !") xl>>ActiveWorkbook>>Close() xl>>Quit() RETOUR END WinPID = Val(ExtraitChaîne(sLigne, 1), 16)
IF EnModeTest() THEN Trace(ObjetActif("Excel.Application") <> Null ? "Actif" ELSE "Inactif") API("User32.dll", "ShowWindow", WinPID, 3) IF EnModeTest() THEN Trace(ObjetActif("Excel.Application") <> Null ? "Actif" ELSE "Inactif")
xl>>Range("A6")>>Value = "1" xl>>Range("A7")>>Value = "2" xl>>Range("A8")>>Value = "3"
FUNCTION EnumWindows(pHndParent est un entier système = -1):chaîne resDLL est un booléen MyHandle, nbChar, Pid est un entier système Patern, Liste, Temp, WindowsListe est une chaîne
WindowsListe = ""
Patern = Répète("Z", 8) + Caract(0x0d) Liste = Répète(Patern, 1000) lpClassName, lpLibellé est une chaîne ASCIIZ sur 9001
IF pHndParent = -1 THEN resDLL = API(user32_dll, "EnumWindows", &EnumWindowsFunction, &Liste) IF NOT resDLL THEN RENVOYER "" ELSE resDLL = API(user32_dll, "EnumChildWindows", pHndParent, &EnumWindowsFunction, &Liste) IF NOT resDLL THEN RENVOYER "" END
Liste = Remplace(Liste, Patern, "") Liste = Liste[[1 A Taille(Liste)-1]]
FOR ALL STRING Temp OF Liste SEPARATED by Caract(0x0d) MyHandle = Val(Temp,"x")
IF pHndParent = -1 THEN xPidParent est un entier système = API(user32_dll, "GetWindowThreadProcessId", MyHandle, &Pid) END lpClassName = Répète(" ", 512) nbChar = API(user32_dll, "GetClassNameA", MyHandle, &lpClassName, Taille(lpClassName)) lpClassName = (nbChar > 0 ? lpClassName[[1 sur nbChar]] ELSE "") lpLibellé = Répète(" ", 512) nbChar = API(user32_dll, "GetWindowTextA", MyHandle, &lpLibellé, Taille(lpLibellé)) lpLibellé = (nbChar > 0 ? lpLibellé[[1 sur nbChar]] ELSE "") IF WindowsListe <> "" THEN WindowsListe += CRLF WindowsListe += NumériqueVersChaîne(MyHandle, "08X") + TAB + SansEspace(lpClassName) + TAB + SansEspace(lpLibellé) END RENVOYER WindowsListe
Testé sur pc Win10-1909 / Windev20-01F200066p/ Excel 2016-pro
-- « L'erreur ne devient pas vérité parce qu'elle se propage et se multiplie ; la vérité ne devient pas erreur parce que nul ne la voit. » Gandhi |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 962 mensajes |
|
| Publicado el 02,mayo 2020 - 00:09 |
hello, en plus simple avec un classeur déjà ouvert par OLE (ne pas lancer excel par un LanceAppli) :
excel est un objet OLE dynamique = ObjetActif("Excel.Application") SI excel <> Null ALORS AppelDLL32("User32.dll","SetForegroundWindow",excel>>hwnd)
-- Ami calmant, J.P |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 948 mensajes |
|
| Publicado el 02,mayo 2020 - 16:00 |
Bonjour Je me doutais bien qu'il y avait plus simple... Je ne connaissais pas le xl>>hwnd qui permet effectivement de simplifier énormément. Du coup il y a deux méthodes : API("User32.dll", "ShowWindow", xl>>hwnd, 3) AppelDLL32("User32.dll","SetForegroundWindow", xl>>hwnd) Bien-vu Jurassic Pork
-- « L'erreur ne devient pas vérité parce qu'elle se propage et se multiplie ; la vérité ne devient pas erreur parce que nul ne la voit. » Gandhi |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 104 mensajes |
|
| Publicado el 03,mayo 2020 - 14:06 |
Effectivement, c'est la méthode que j'avais retenue entre temps.
J'hésitais à le faire car je me souvenais qu'il y a maintenant des restrictions Windows pour forcer à passer une fenêtre au premier-plan : (illustré ici par exemple : https://gist.github.com/EBNull/1419093). Mais en fait, je pense que la restriction lorsque l'on veut passer "soi-même" au premier-plan.
Par contre, quand on veut passer une autre fenêtre, il y a maintenant une procédure similaire dans Windev, SysFenActive qui je suppose fait la même chose que SetForegroundWindow. Donc, cela donne le code ci-dessous. Ce qui n'empêche pas PC Soft de réfléchir pourquoi ObjetActif avec Excel ne fonctionne pas dans certains cas (alors que cela fonctionne très bien avec Word par exemple). Mais c'est une autre histoire...
v_obj_xls est un objet automation "Excel.Application" v_obj_xls>>Visible = Vrai
ET enfin SI v_obj_xl <> Null ALORS SysFenActive(v_obj_xls>>hWnd) |
| |
| |
| | | |
|
| | | | |
| | |
|