Aus PB Excel-Datei mit mehreren Tabellenblättern erstellen?

Für allgemeine Fragen zur Programmierung mit PureBasic.
schic
Beiträge: 68
Registriert: 25.12.2004 19:04

Beitrag von schic »

einige Beispiele wie Autowrap mit Excel verwendet wird.

Zelle auslesen, der Typ (Text oder Zahl) muß bekannt sein:

Code: Alles auswählen

Procedure.l XLGetCellsValue(*sheet.IDispatch, Row, Column, vtType.l = 0)
  Shared tmpText$, qtmp.d
  
;VBA: *sheet.Cells(Row, Column).Value
  Dim varArr.VARIANT(2)
  varArr(0)\vt = #VT_I4
  varArr(0)\lVal = Column
  varArr(1)\vt = #VT_I4
  varArr(1)\lVal = Row
  pXlCells_x_y.IDispatch
  pvResult.VARIANT
  VariantInit_(@pvResult);
  AutoWrap(#DISPATCH_PROPERTYGET, *sheet, "Cells", 2)
  pXlCells_x_y = pvResult\pdispVal
  
  VariantInit_(pvResult.VARIANT)
  AutoWrap(#DISPATCH_PROPERTYGET,  pXlCells_x_y, "Value", 0)
  ;Debug "pvResult\vt: " + Str(pvResult\vt)
  Select pvResult\vt
    Case #VT_BSTR; Text
      tmpText$ = Uni2Ansi(pvResult\bstrVal)
      result = @tmpText$
      
    Case #VT_R8;Zahl
      qtmp = pvResult\dblVal
      If vtType = #VT_BSTR
        tmpText$ = StrD(PeekD(@qtmp),3)
        result = @tmpText$
      Else
        result = @qtmp
      EndIf
      
  EndSelect
  
  VariantClear_(varArr(0))
  VariantClear_(varArr(1))
  VariantClear_(pvResult)
  
  SetObjNothing(pXlCells_x_y)
  
  ProcedureReturn result;tmpText$
EndProcedure


*tmp = XLGetCellsValue(pXlSheet, Row, 7)
If *tmp
    Zahl.d = PeekD(*tmp); 
Endif

*tmp = XLGetCellsValue(pXlSheetKN, Row, 4) 
If *tmp
    tmpTxt$ = PeekS(*tmp)
Endif
VBA-Makro starten:

Code: Alles auswählen

Procedure XlRunMakro(*XlApp.IDispatch, Makro.s)
  Dim varArr.VARIANT(1)
  varArr(0)\vt = #VT_BSTR
  varArr(0)\bstrVal = Ansi2Uni(@Makro)
  AutoWrap(#DISPATCH_METHOD, *XlApp, "Run", 1)
  VariantClear_(varArr(0))
EndProcedure
Zelle aktivieren:

Code: Alles auswählen

Procedure XlSelectCells(*sheet.IDispatch, Row, Column)
  Dim varArr.VARIANT(1)
  varArr(0)\vt = #VT_I4
  varArr(0)\lVal = Column
  varArr(1)\vt = #VT_I4
  varArr(1)\lVal = Row
  pXlCells_x_y.IDispatch
  pvResult.VARIANT
  VariantInit_(@pvResult);
  AutoWrap(#DISPATCH_PROPERTYGET, *sheet, "Cells", 2)
  pXlCells_x_y = pvResult\pdispVal
  AutoWrap(#DISPATCH_METHOD, pXlCells_x_y, "Select", 0)
  VariantClear_(varArr(0))
  VariantClear_(varArr(1))
  SetObjNothing(pXlCells_x_y)
EndProcedure
xls-Datei öffnen:

Code: Alles auswählen

  varArr(0)\vt = #VT_BSTR
  varArr(0)\bstrVal = Ansi2Uni(@File$);File$=xls-Datei
  AutoWrap(#DISPATCH_METHOD, pXlBooks, "Open", 1)
  VariantClear_(varArr(0))
Objektzeiger eines bestimmten Tabellenblattes mit Blattnamen bekommen:

Code: Alles auswählen

  varArr(0)\vt = #VT_BSTR
  varArr(0)\bstrVal = Ansi2Uni(@"Blattname")
  pXlSheetKN.IDispatch = SetComObj(pXlApp, "Worksheets", 1)
  VariantClear_(varArr(0))
Zellenbreite an Inhalt anpassen, VBA-Code: Cells.EntireColumn.AutoFit

Code: Alles auswählen

;get cells object
pXlCells.IDispatch ;= SetComObj(pXlSheet, "Cells", 0)
Debug "pXlCells: " + Str(pXlCells)
VariantInit_(@pvResult)
AutoWrap(#DISPATCH_PROPERTYGET, pXlSheet, "Cells", 0)
pXlCells = pvResult\pdispVal

;get EntireColumn-object
pXlEntireColumn.IDispatch = SetComObj(pXlCells, "EntireColumn", 0)

AutoWrap(#DISPATCH_METHOD, pXlEntireColumn, "AutoFit", 0)
;}
Gruß
Christian
Benutzeravatar
dysti
Beiträge: 656
Registriert: 10.02.2006 18:34
Wohnort: Schlicktown

Beitrag von dysti »

Hallo @schic,

Diese Zeilen machen Ärger:

Code: Alles auswählen

varArr(0)\bstrVal = Ansi2Uni(@File$)
oder

Code: Alles auswählen

varArr(0)\bstrVal = Ansi2Uni(@Makro)
usw.

Bekomme folgende Fehlermeldung immer an diesen Stellen:
  • Bad parameter type: a string is expected


Was ist nicht korrekt?
PB5 / Spiderbasic / WB14 / Win7 / Win8.1 / Win10 / Debian 9
Benutzeravatar
Karl
Beiträge: 520
Registriert: 21.07.2005 13:57
Wohnort: zu Hause

Beitrag von Karl »

@Schic:

Da du ja dich bereits tief hinein gearbeitet hast, wäre es doch großartig, wenn du daraus eine UserLib basteln könntest :allright:

Das wäre doch mal was.

Der Karl
The Kopyright Liberation Front also known as the justified ancients of Mumu!
PB 5.X
Benutzeravatar
dysti
Beiträge: 656
Registriert: 10.02.2006 18:34
Wohnort: Schlicktown

Beitrag von dysti »

@Karl, da muß ich dir zustimmen.
PB5 / Spiderbasic / WB14 / Win7 / Win8.1 / Win10 / Debian 9
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3873
Registriert: 13.09.2004 17:48
Kontaktdaten:

Beitrag von bobobo »

keine Lib bitte .. mach ne Include .. wär besser zum späteren Anpassen
‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
schic
Beiträge: 68
Registriert: 25.12.2004 19:04

Beitrag von schic »

@dysti: ohne das @ vor dem String funktionierts. Habe mal die Ansi2Uni auf
Zeiger-Argument geändert und die Procedure daraus gepostet, ohne darauf
zu achten.

@Karl + @bobobo:
ich mag Libs auch nicht so gerne, da man nicht mehr so flexibel damit ist.
Als Include verwende ich das Autowrap-Gerüst so wie´s ist. Könnte zwar
komfortabler sein, aber dafür ist´s universell einsetzbar. Die IDispatch
interfaces fonktionieren ja nicht nur mit Excel, sondern mit allem,
was COM (ActiveX) unterstützt.
Naja und alle Excelfunktionen nachzubilden, nur damit es ein bisschen
komfortabler zum proggen ist, ist mir der Aufwand zu groß. Außerdem
wäre das eine saulangweilige Arbeit.
Was ich schon überlege, ist, einen Disphelper wie auf
http://disphelper.sourceforge.net/ gezeigt, als include mit PB zu schreiben.
Leider fehlt mir dazu die Zeit.

Es sei aber niemandem verwehrt meinen Code als Grundgerüst für so ein
Projekt zu verwenden ;-) stehe auch gerne mit Rat und Tat zur Seite...

Gruß
Christian
Benutzeravatar
dysti
Beiträge: 656
Registriert: 10.02.2006 18:34
Wohnort: Schlicktown

Beitrag von dysti »

Hey @schic,

bin am verzweifeln. Es öffnet sich Exel, aber die Datei "test.xls" wird nicht angezeigt.
Der Debugger meldet: Worksheets NOT o.k.

Hier der Code:

Code: Alles auswählen

IncludeFile "exelwrapper.pb"

pXlApp.IDispatch = SetAppObj("Excel.Application") ; create the object Excel -> Set pXlApp = Excel.Application
If pXlApp = 0
  Debug LastMessage
  End
EndIf



;{ make application visible (
Dim varArr.VARIANT(1)
varArr(0)\vt = #VT_I4 ;Variant-Value
varArr(0)\lVal = 1    ;for TRUE (=1)
AutoWrap(#DISPATCH_PROPERTYPUT, pXlApp, "Visible", 1); put the value "TRUE" to the property Visible -> pXlApp.Visible = True
VariantClear_(varArr(0))
;}

pXlBooks.IDispatch = SetComObj(pXlApp, "Workbooks", 0); get the Workbookslist-Object -> Set pXlBooks = pXlApp.Workbooks





;{ add a workbook, VBA-Code: pXlBooks.Add
pXlBook.IDispatch ;init the dispatch interface for the workbook
pvResult.VARIANT
VariantInit_(@pvResult);
AutoWrap(#DISPATCH_PROPERTYGET, pXlBooks, "Add", 0); call the method "Add" from Workbooks
pXlBook = pvResult\pdispVal
;}



pXlSheets.IDispatch = SetComObj(pXlBook, "Sheets", 0); getting the Sheetslist-Object -> Set pXlSheets = pXlBook.Sheets

 

File$="test.xls"
varArr(0)\vt = #VT_BSTR
  varArr(0)\bstrVal = Ansi2Uni(File$);File$=xls-Datei
  AutoWrap(#DISPATCH_METHOD, pXlBooks, "Open", 1)
  VariantClear_(varArr(0)) 


varArr(0)\vt = #VT_BSTR
  varArr(0)\bstrVal = Ansi2Uni("Tabelle1")
  ;pXlSheetKN.IDispatch = SetComObj(pXlApp, "Worksheets", 1)
  pXlSheetKN.IDispatch = SetComObj(pXlBooks, "Worksheets", 1)
  VariantClear_(varArr(0)) 

  
;*tmp = XLGetCellsValue(pXlSheetKN, 1, 1)
;If *tmp
;    tmpTxt$ = PeekS(*tmp)
;EndIf
PB5 / Spiderbasic / WB14 / Win7 / Win8.1 / Win10 / Debian 9
schic
Beiträge: 68
Registriert: 25.12.2004 19:04

Beitrag von schic »

der fehler ist bei File$="test.xls", hier musst Du den gesamten Pfad mit angeben.
z.B. File$="c:\test.xls"

Wenn Du die Debug-Ausgabe beachtest, wirdt Du feststellen, daß schon bei der Methode Open kein S_Ok zurückgegeben wird.
schic
Beiträge: 68
Registriert: 25.12.2004 19:04

Beitrag von schic »

noch ein Fehler:

Worksheets ist eine Eigenschaft des Application-Objekts.
Aus der Excel-VBA-Hilfe:
Worksheets-Eigenschaft

Gibt für ein Application-Objekt eine Sheets-Auflistung aller Arbeitsblätter der aktiven Arbeitsmappe zurück. Gibt für ein Workbook-Objekt eine Sheets-Auflistung zurück, die alle Arbeitsblätter in der angegebenen Arbeitsmappe darstellt. Schreibgeschütztes Sheets-Objekt.
Du versuchst aus der Workbooks-Auflistung (pXlBooks) die Sheests-Liste zu bekommen:

Code: Alles auswählen

pXlSheetKN.IDispatch = SetComObj(pXlBooks, "Worksheets", 1)
Workbooks ist aber eine Eigenschaft des Application-Objekts
Application
|_Workbooks
|_Workbook

Entweder Du nimmst das Application-Objekt (pXlApp) oder holst Dir vorher das Workbook-Objekt (nicht die Liste).
Benutzeravatar
dysti
Beiträge: 656
Registriert: 10.02.2006 18:34
Wohnort: Schlicktown

Beitrag von dysti »

@schic,

die Routine "Datei öffnen" funktioniert nicht. :cry:
Normalerweise sollte "hr invoke: 0" herauskommen, satt dessen eine lange Zahl. Siehe Bild.

Bild

Der Code sieht jetzt so aus:

Code: Alles auswählen

File$="C:\tmp\test.xls"
varArr(0)\vt = #VT_BSTR
  varArr(0)\bstrVal = Ansi2Uni(File$);File$=xls-Datei
  AutoWrap(#DISPATCH_METHOD, pXlBooks, "Open", 1)  
  VariantClear_(varArr(0)) 
Was läuft das verkehrt?
PB5 / Spiderbasic / WB14 / Win7 / Win8.1 / Win10 / Debian 9
Antworten