AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

AnsiStringArray aus DLL an Excel-VBA

Ein Thema von Andreas13 · begonnen am 25. Apr 2019 · letzter Beitrag vom 10. Mai 2019
Antwort Antwort
Seite 2 von 2     12   
EWeiss
(Gast)

n/a Beiträge
 
#11

AW: AnsiStringArray aus DLL an Excel-VBA

  Alt 29. Apr 2019, 16:27
Zitat:
Könntest Du bitte den Code in der beiliegenden Datei ToExcel_Test_1.xlsm bei Gelegenheit evtl. so anpassen, daß es "dort" in Excel läuft?
Würde dir da gerne helfen habe aber kein VBA Exel. (Office) installiert.

gruss

Geändert von EWeiss (29. Apr 2019 um 19:37 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#12

AW: AnsiStringArray aus DLL an Excel-VBA

  Alt 29. Apr 2019, 18:54
Was ich dir aber sagen kann das mein Modul so unter Excel 64Bit nicht läuft. (Keine Ahnung was du installiert hast)
Es fehlt PtrSafe in allen Declarationen.
Dann muss die DLL von Delphi auch in 64Bit vorliegen.
Zur Kompatibilität der Daten Typen

Code:
Option Explicit

Private Declare PtrSafe Function PAnsiChar_To_Excel Lib "Delphi_String_for_Excel_Test.dll" ( _
    Optional ByVal Delimiter As Byte = 59 _
) As LongPtr

Private Declare PtrSafe Function lstrlen Lib "kernel32" Alias "lstrlenA" ( _
    ByVal lpString As Long _
) As LongPtr

Public Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
    ByRef Destination As Any, _
    ByRef Source As Any, _
    ByVal length As LongPtr_
)
So sollte es aussehen.
Eventuell kommst du ja jetzt weiter.

Für die ListBox\ListenFeld könntest du dir ja ein Array erstellen ( bzw. haben wir schon alist() ) und das anstelle dessen verwenden wenn du keine UserForm verwenden möchtest.
Oder du schickst die werte von alist() direkt in deine Excel Tabelle.

https://analysistabs.com/vba-code/ex...rform/listbox/
https://www.guru99.com/creating-your...-in-excel.html

PS:
Anstelle des Button kannst du dir in Excel ein Macro erstellen was auf die cmdGet_Click() verweist und den Code dort ausführen.

gruss

Geändert von EWeiss (30. Apr 2019 um 18:26 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#13

AW: AnsiStringArray aus DLL an Excel-VBA

  Alt 30. Apr 2019, 00:09
Habe mal Excel 32Bit installiert aber keine Ahnung ob es das ist was du willst..
Ich werde da nicht so recht schlau draus.

Klick auf Button GetIt füllt die Cells in Excel
Klick auf Button CleanUp löscht die Einträge.

Ohne Form und ausgeführt in Excel!

Code:
Option Explicit

'                                              Pfad aktualisieren:
Private Declare Function PAnsiChar_To_Excel Lib "D:\Test\Delphi_String_for_Excel_Test" ( _
    Optional ByVal Delimiter As Byte = 59 _
) As Long

Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" ( _
    ByVal lpString As Long _
) As Long

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
    ByRef Destination As Any, _
    ByRef Source As Any, _
    ByVal length As Long _
)

Private Function VBStrFromAnsiPtr(ByVal lpStr As Long) As String

Dim bStr() As Byte
Dim cChars As Long

    On Error Resume Next
        ' Get the number of characters in the buffer
        cChars = lstrlen(lpStr)
        If cChars Then
            ' Resize the byte array
            ReDim bStr(0 To cChars - 1) As Byte
            ' Grab the ANSI buffer
            Call CopyMemory(bStr(0), ByVal lpStr, cChars)
        End If
        ' Now convert to a VB Unicode string
        VBStrFromAnsiPtr = StrConv(bStr, vbUnicode)

End Function

Private Sub CleanUp()

    Range("B1:B4").Delete XlDeleteShiftDirection.xlShiftUp

End Sub

Private Sub GetIt()

Dim flist    As String
Dim LngP     As Long
Dim alist()  As String
Dim Delimiter As Byte
Dim arTesting As Variant

    Delimiter = 124

    LngP = PAnsiChar_To_Excel(Delimiter) ' >>> "|"

    flist = VBStrFromAnsiPtr(LngP)
    alist = Split(flist, "|")

    If flist > "" Then
        arTesting = Application.WorksheetFunction.Transpose(alist)
        Range("B1:B4").Value = arTesting
    End If

End Sub
Wie du das nun schlussendlich regelst über Button oder sonst wie entscheide es selbst..
Aber der Wunsch die Strings in einem Schub nach Excel zu transponieren sollte dem entsprechen.
Delphi > VBA > Excel

Ich hoffe du kommst mit dem Rest selber klar.

gruss

Geändert von EWeiss (11. Jul 2019 um 16:59 Uhr)
  Mit Zitat antworten Zitat
Dennis07

Registriert seit: 19. Sep 2011
Ort: Deutschland
485 Beiträge
 
Delphi 11 Alexandria
 
#14

AW: AnsiStringArray aus DLL an Excel-VBA

  Alt 30. Apr 2019, 00:35
Delphi-Quellcode:
 Procedure AnsiStringVektor_To_Excel(S: PAnsiChar; n_Anzahl: ExcelLongInt); StdCall;
// Aufgabe -> Einen Delphi-AnsiString-Vektor auf EINMAL an Excel-VBA übertragen

// S: PAnsiChar : Erstes Element des zu zu übertragenden StringVektors
// n_Anzahl: ExcelLongInt : Gesamtzahl der Strings im StringVektor


VAR
  Vektor: Array of PAnsiChar ABSOLUTE S;
  P : AnsiString;
  i : Integer;
  
Begin
  For i:= 1 To n_Anzahl Do // Excel: 1-basiertes Array
  Begin
    P:= AnsiString_Vektor_Global[i-1]; // -1: Delphi: 0-basiertes Array

    System.AnsiStrings.StrPLCopy(Vektor[i], P, Length(P)); // --> Access violation
    // System.AnsiStrings.StrCopy(PAnsiChar(Vektor[i]), PAnsiChar(P)); // --> Access violation
  End;
End;{AnsiStringVektor_To_Excel}
Naja, also so geht das ja nicht. Ein array of PAnsiChar ist ja kein PAnsiChar , sondern ein PPAnsiChar (Arrays sind Zeiger auf ihr erstes element, mit der Länge, dem Referenzzähler und der Typeninfo vorweg). absolute gibt dir zwar im gegensatz zu einem Typecast keinen Fehler aus, aber das heißt nicht, dass es so richtig ist.
Richtig muss S aber entweder ein PPAnsiChar oder Vektor ein array of AnsiChar (bzw. ein PAnsiChar ) sein.
Auch kommt da jetzt noch folgendes hinzu: Arrays sind ja, wie eben schon gesagt, sowohl referenzgezählt, als auch typisiert und haben eine feste Länge. Gut möglich, dass dir das somit auch nochmal den Speicher zerschießt, da dafür in dem PAnsiChar ja gar nichts reserviert ist.
Dennis

Geändert von Dennis07 (30. Apr 2019 um 00:40 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#15

AW: AnsiStringArray aus DLL an Excel-VBA

  Alt 30. Apr 2019, 00:38
Sorry du kramst altes Zeug raus das mittlerweile auf anderem Wege schon gelöst ist.

gruss
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
719 Beiträge
 
Delphi XE5 Professional
 
#16

AW: AnsiStringArray aus DLL an Excel-VBA

  Alt 30. Apr 2019, 15:26
Danke für Deine VBA-Lösung!
Ich habe sie so abgewandelt, daß der Text sofort in den Excel-Zellen erscheint. Dazu brauchen wir eine neue Funktion in Excel's VBA wie folgt:

VBA-Code
Delphi-Quellcode:
Public Function GetDelphiStringVektor(Anzahl As Long) ' entweder OHNE Typangabe oder As Variant, was gleichbedeutend ist, da dies eine Matrix-Funktion sein soll
' ... und so geht es direkt in die Zellen

Dim flist As String
Dim LngP As Long
Dim alist() As String

Const Delimiter = 124

Dim StrVektor() As String
Dim i As Long
Dim n_Anz As Long
Dim Bis As Long

  LngP = PAnsiChar_To_Excel(Delimiter) ' >>> "|"

flist = VBStrFromAnsiPtr(LngP)
alist = Split(flist, "|")

n_Anz = UBound(alist) - LBound(alist) + 1

Bis = Anzahl
If n_Anz < Anzahl Then Bis = n_Anz
' Hat denn VBA keine Funktion wie Pascal's Min?? --> Bis := Min(a_Anz, Anzahl)

ReDim StrVektor(n_Anz, 0 To 0)
' SpaltenVektor

  If flist > "" Then
    For i = LBound(alist) To Bis - 1
      StrVektor(i, 0) = alist(i)
    Next
  End If

  GetDelphiStringVektor = StrVektor
End Function
Die beiden Lösungen sind zum Ausprobieren im beiliegenden Excel-File ToExcel_Test_2.xlsm vorhanden. Die DLL bleibt unverändert, daher habe ich sie nicht noch einmal hochgeladen.

Gruß, Andreas
Angehängte Dateien
Dateityp: zip ToExcel_Test_2.zip (19,6 KB, 5x aufgerufen)

Geändert von Andreas13 (30. Apr 2019 um 15:29 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#17

AW: AnsiStringArray aus DLL an Excel-VBA

  Alt 30. Apr 2019, 15:33
Zitat:
Ich habe sie so abgewandelt
Wie ich schon sagte es bleibt dir überlassen wie du das später auslegen willst.

Aber gut wenn es jetzt funktioniert.
Mein Lösungsansatz war nur als Denkanstoß gedacht.

Zitat:
' Hat denn VBA keine Funktion wie Pascal's Min?? --> Bis := Min(a_Anz, Anzahl)
Min ist eine Excel Funktion oder?
Code:
WorksheetFunction.Min(20, 501, 561, 45, 78)
Wenn du das nicht willst dann mache dir selber was wenn du denkst es ist von nöten.
LBound = MIN
UBound = MAX

Code:
Private Function Min(ParamArray values() As Variant) As Variant
Dim i As Integer
Dim min_value As Variant

    min_value = values(LBound(values))
    For i = LBound(values) + 1 To UBound(values)
        If min_value > values(i) Then min_value = values(i)
    Next

    Min = min_value
End Function

Private Function Max(ParamArray values() As Variant) As Variant
Dim i As Integer
Dim max_value As Variant

    max_value = values(LBound(values))
    For i = LBound(values) + 1 To UBound(values)
        If max_value < values(i) Then max_value = values(i)
    Next

    Max = max_value
End Function

' Teste Min, Max
Private Sub cmdGo_Click()
    txtMin.Text = Format$(Min( _
        CInt("2873"), _
        CInt("4398"), _
        CInt("7846"), _
        CInt("1876"), _
        CInt("4792"), _
        CInt("3982"), _
        CInt("4863"), _
        CInt("9382")))
   
    txtMax.Text = Format$(Max( _
        CInt("2873"), _
        CInt("4398"), _
        CInt("7846"), _
        CInt("1876"), _
        CInt("4792"), _
        CInt("3982"), _
        CInt("4863"), _
        CInt("9382")))
End Sub
Code:
Const Delimiter = 124
Etwas unsauber weil du hier Delimiter ohne Angabe als Variant definierst.. ist aber Byte!
Wenn dann so!
Code:
Const Delimiter As Byte = 124
Siehe die Definition von PAnsiChar_To_Excel(bla bla.. Delimiter As Byte
Code:
Dim i As Long
Dim n_Anz As Long
Dim Bis As Long
zu
Code:
Dim i As Integer
Dim n_Anz As Integer
Dim Bis As Integer
Ein 32Bit DatenTyp ist für einfache for.. Next schleifen nicht nötig.
Zitat:
Die beiden Lösungen sind zum Ausprobieren im beiliegenden Excel-File ToExcel_Test_2.xlsm vorhanden
Habe Office wieder deinstalliert da ich es eigentlich nicht brauche und es nur eine Test Version war.

PS:
VBA ist kein Delphi daher wäre es besser du verwendest die Format Funktion des Forum
Code:
Dim x As Integer
Dim i As Integer
nicht
Delphi-Quellcode:
var
  x:Integer;
  i:Integer;
dann liest es sich besser.

gruss

Geändert von EWeiss ( 9. Jul 2019 um 09:32 Uhr)
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
719 Beiträge
 
Delphi XE5 Professional
 
#18

AW: AnsiStringArray aus DLL an Excel-VBA

  Alt 30. Apr 2019, 17:08
Danke, die Format-Funktion für den sonstigen Code habe ich erst jetzt gefunden...

Gruß, Andreas
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#19

AW: AnsiStringArray aus DLL an Excel-VBA

  Alt 10. Mai 2019, 12:40
Sorry das ich das nochmal vor krame..
Habe das vorhin nochmal gelesen und festgestellt das deine abfrage auf
Code:
  If flist > "" Then
viele zu spät kommt..

Was machst du wenn
Code:
If flist = ""
ist?

Dann wird das Array alist() nicht initialisiert und die nächste Abfrage lässt deine Anwendung abstürzen.
Code:
alist = Split(flist, "|")
n_Anz = UBound(alist) - LBound(alist) + 1
mache es direkt nach der Initialisierung von flist.

Code:
Public Function GetDelphiStringVektor(Anzahl As Long) As Variant

 Dim flist As String
 Dim LngP As Long
 Dim alist() As String

 Const Delimiter As Byte = 124

 Dim StrVektor() As String
 Dim i As Long
 Dim n_Anz As Long
 Dim Bis As Long

    LngP = PAnsiChar_To_Excel(Delimiter) ' >>> "|"

    flist = VBStrFromAnsiPtr(LngP)
    If flist > "" Then
        alist = Split(flist, "|")

        n_Anz = UBound(alist) - LBound(alist) + 1

        Bis = Anzahl
        If n_Anz < Anzahl Then Bis = n_Anz

        ReDim StrVektor(n_Anz, 0 To 0) ' SpaltenVektor
 
        For i = LBound(alist) To Bis - 1
            StrVektor(i, 0) = alist(i)
        Next

        GetDelphiStringVektor = StrVektor
    else
        GetDelphiStringVektor = ""
    End If

End Function
gruss
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
719 Beiträge
 
Delphi XE5 Professional
 
#20

AW: AnsiStringArray aus DLL an Excel-VBA

  Alt 10. Mai 2019, 17:12
@EWeiss

Hab herzlichen Dank für die Verbesserungen!
Gruß
Andreas
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:48 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz