XL 2019 Cherche Volontaires pour tester dll interface VBA Dotnet

jurassic pork

XLDnaute Occasionnel
Hello,
j'ai créer des dll (1 en 32 bits et 1 en 64 bits) pour appeler des fonctions écrites en dotnet à partir du VBA. Les fonctions sont à l'intérieur des dll mais les dll ne sont pas des assemblages mais l'équivalent des dll API windows (unmanagedExports). Ces fonctions permettent entre autres de lancer des commandes PowerShell et de récupérer le résultat, de trier des tableaux, de mélanger les éléments de tableaux, de faire des temporisations en millisecondes, de manipuler le presse papier (pas seulement le texte mais aussi les images), de faire des splits multi séparateurs et des replace spéciaux ( par regex). Les dlls sont très petites ( < 40k ) . Elles sont faciles à mettre en oeuvre puisqu'il suffit de faire une déclaration dans un module VBA comme ceci :
VB:
#If Win64 Then
    Declare PtrSafe Function CreatePressePapierClass Lib "D:\Tmp\ClassesCSharpJP\ClassesCSharpJPx64.dll" () As Object
    Declare PtrSafe Function CreatePowerShellClass Lib "D:\Tmp\ClassesCSharpJP\ClassesCSharpJPx64.dll" () As Object
    Declare PtrSafe Function CreateUtilsClass Lib "D:\Tmp\ClassesCSharpJP\ClassesCSharpJPx64.dll" () As Object
#Else
    Declare PtrSafe Function CreatePressePapierClass Lib "D:\Tmp\ClassesCSharpJP\ClassesCSharpJPx86.dll" () As Object
    Declare PtrSafe Function CreatePowerShellClass Lib "D:\Tmp\ClassesCSharpJP\ClassesCSharpJPx86.dll" () As Object
    Declare PtrSafe Function CreateUtilsClass Lib "D:\Tmp\ClassesCSharpJP\ClassesCSharpJPx86.dll" () As Object
#End If
En pièce jointe il y a les dlls (dans le zip) et un classeur de démonstration. Voici par exemple ce que l'on peut faire dans le classeur :
DemoClasses.gif

Voici un exemple de code de comment appeler une fonction et récupérer le résultat :
VB:
Sub TestPowerShell()
Dim Resultat
Dim Pwsh As Object
Set Pwsh = CreatePowerShellClass()
' On récupère la date du dernier boot de l ordinateur par une commande powershell wmi
Resultat = Pwsh.ExecuteCmd("Get-WmiObject win32_operatingsystem | " & _
                           "select @{LABEL=’LastBootUpTime’;EXPRESSION=" & _
                           "{$_.ConverttoDateTime($_.lastbootuptime)}} | Out-String")
Debug.Print Resultat
Worksheets("PowerShell").Range("A2") = Resultat
End Sub
Normalement au point de vue performance et temps d'exécution cela est rapide car on ne passe pas par la couche COM et le powershell est appelé par son assemblage dotnet pas par une commande console.
A vous de tester ce qui est proposé dans le classeur de démo et de me dire si cela fonctionne et avec quelle configuration (O.S et version d'Excel). Si cela ne fonctionne pas me le dire aussi avec les messages d'erreurs. Les fonctions dans les dll utilisent le framework dotnet de type 4.x qui normalement est installé (ou pré installé) sur tous les windows récents.
J'ai des doutes sur le fonctionnement des dll sur des O.S antérieurs à windows 8 et des Excel antérieurs à 2010. Moi j'ai testé en Windows 11 Excel 2019 32 bits et Excel 2021 64 bits. Merci d'avance pour les personnes qui vont faire les tests. Si cela s'avère positif, ces petites dlls pourront servir en complément. Je pourrais peut-être aussi les enrichir avec des fonctions qui manquent cruellement à VBA.
Les dlls ont une licence de type MIT.
Ami calmant, J.P
 

Pièces jointes

  • DemoClassesCsharpJP.xlsm
    82.5 KB · Affichages: 3
  • ClassesCsharpJP.zip
    15.5 KB · Affichages: 4

patricktoulon

XLDnaute Barbatruc
Bonjour très vieux cochon

office 2013 32 bit pro

Édition Windows 10 Professionnel
Version 22H2
Installé le ‎28/‎07/‎2023
Build du système d’exploitation 19045.4780
Expérience Windows Feature Experience Pack xxxx.xxxx.xxxxxx


VB:
#If Win64 Then
    Declare PtrSafe Function CreatePressePapierClass Lib "C:\autres dll\ClassesCSharpJPx164.dll" () As Object
    Declare PtrSafe Function CreatePowerShellClass Lib "C:\autres dll\ClassesCSharpJPx164.dll" () As Object
    Declare PtrSafe Function CreateUtilsClass Lib "C:\autres dll\ClassesCSharpJPx164.dll" () As Object
    Declare PtrSafe Function CreateTextUtilsClass Lib "C:\autres dll\ClassesCSharpJPx164.dll" () As Object
#Else
    Declare PtrSafe Function CreatePressePapierClass Lib "C:\autres dll\ClassesCSharpJPx86.dll" () As Object
    Declare PtrSafe Function CreatePowerShellClass Lib "C:\autres dll\ClassesCSharpJPx86.dll" () As Object
    Declare PtrSafe Function CreateUtilsClass Lib "C:\autres dll\ClassesCSharpJPx86.dll" () As Object
    Declare PtrSafe Function CreateTextUtilsClass Lib "C:\autres dll\ClassesCSharpJPx86.dll" () As Object
#End If

demo1.gif


les procc
demo1.gif


le last bootUp
demo1.gif

pour la capture
demo1.gif


j'ai vérifié avec le module GDI+ d'harkam de dvp Ma Dll Gdi+ fonctionne très bien
proposition d'ajouter au pack un cmd pour installer les dll 64 ou 32
pour ne plus avoir le chemin complet dans les déclarations
Code:
@echo off
setlocal

:: Titre du script
title Enregistrement des DLLs 32 bits et 64 bits

:: Définir les chemins des DLLs
set "dll32=C:\autres dll\ClassesCSharpJPx86.dll"  :: Remplacez ce chemin par celui de votre DLL 32 bits
set "dll64=C:\autres dll\ClassesCSharpJPx64.dll"  :: Remplacez ce chemin par celui de votre DLL 64 bits

:: Vérifier l'architecture du système
if "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
    echo Système 64 bits détecté.
    echo Enregistrement de la DLL 64 bits...
    regsvr32 /s "%dll64%"
    if %errorlevel% equ 0 (
        echo DLL 64 bits enregistrée avec succès.
    ) else (
        echo Échec de l'enregistrement de la DLL 64 bits.
    )
) else (
    echo Système 32 bits détecté.
    echo Enregistrement de la DLL 32 bits...
    regsvr32 /s "%dll32%"
    if %errorlevel% equ 0 (
        echo DLL 32 bits enregistrée avec succès.
    ) else (
        echo Échec de l'enregistrement de la DLL 32 bits.
    )
)

:: Fin du script
pause
exit /b 0

patrick ;)
 

jurassic pork

XLDnaute Occasionnel
Hello patrick,
merci d'avoir testé. Ton erreur avec le presse papier c'est certainement que le chemin de sauvegarde de l'image n'existe pas sur ton pc (j'ai la même erreur que toi quand je mets un chemin qui n'existe pas).
VB:
pp.SaveImage "d:\temp\range.png", 0
 

patricktoulon

XLDnaute Barbatruc
re
pense tu ;)
tu te doute bien que je l'ai changé
1724334039444.png

mais en effet tu a raison l’écriture direct dans C m'est interdite j'ai testé avec un compte windows non administrateur
j'ai essayé thisworkbook.path &"\range.png" et ça marche

par contre a l'analyse avec GIMP je ne suis pas sur que ce soit un vrai png

edit :je confirme à 100% ce n'est pas un vrai png !!
 

jurassic pork

XLDnaute Occasionnel
j'ai comparé ta fonction GenRandomArrayDbl a la mienne en vba

c'est a dire restitution de 1000 item de 1 à 5000(là ici pas trop de différence)

mais quand je restitue les 5000 là on vois bien la différence et je suis de loin plus rapide
c'est normale que tu sois plus rapide sur des fonctions pur VBA
Je rappelle que le but de la discussion c'est pas de comparer mais de dire si cela fonctionne ou pas.
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
oui tu vois type png dans les prop par ce que c'est comme ça que l'image a été encapsullée
ton image na pas de calque mask
toute les png ont un calque mask (même transparent si il faut qui sert a rien )
en f"ait c'est un bitmap encapsullé d"ans un conteneur png
alors oui Windows et les app dessin la lisent m"ais ce n'est en aucun c"as un vrai png
d'"ailleurs il sufit de l'ouvrir "avec open acces read binary pour y voir dans les 5 premier bits le tableau de bits d'un jpg ou bitmap

j'ai d'ailleurs essayé de copier une shape ronde "avec copy et ou copypicture pour la transparence
et ca me la restitue bien sur fond blanc
1724336343141.png


et voilà comment elle sort dans photo de windows

1724336426249.png

c'est normale que tu sois plus rapide sur des fonctions pur VBA
ben non justement

sinon après c'est pas mal pour les chaines de caractère là par contre vba ne rivalisera pas je pense
D"ans tout les cas l'exercice est intéréssant

quel procédé logique utilise plus pour ta liste aléatoire de nombre ????
je pense que tu pourrais adapter la logique que j'utilise mais dans ta dll
a savoir non pas le choix d'un nombre aléatoire x fois mais le mélange x fois dans un tableau de nombre


voici la logique que j'utilise
je pense que c'est plus intelligent d'utiliser la fonction random d'un langage comme ca
et surtout on a pas traiter d'éventuels doublons ;)
VB:
Function GenRandomArrayDblVpat(Deb, Fin)
   'patricktoulon
   Dim A, Tp, X
    A = Evaluate("transpose(row(" & Deb & ":" & Fin & "))") 'on crée le tableau de nombre (array 1 dim)
    For i = LBound(A) To UBound(A) 'boucle  de 1 à ubound
        X = 1 + (Rnd * (UBound(A) - 1)) 'selection d'un index au hasard
        Tp = A(i): A(i) = A(X): A(X) = Tp 'intervertion de l'index i et x
    Next
    'terminé on a un array de nombre aleatoire sans doublon
    GenRandomArrayDblVpat = A
End Function

Sub test()
    arr = GenRandomArrayDblVpat(1, 5000) '"appel la creation d'un array aleatoire
    [a2].Resize(1000) = Application.Transpose(arr) 'restitution sur 1000 cellules
End Sub
 

Discussions similaires

  • Résolu(e)
Microsoft 365 32 ou 64 bits
Réponses
46
Affichages
1 K

Statistiques des forums

Discussions
313 866
Messages
2 103 082
Membres
108 521
dernier inscrit
manouba