ExcelFunktionen COMatePlus

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
jear
Beiträge: 288
Registriert: 17.10.2004 01:59
Wohnort: Ammerland

Re: ExcelFunktionen PureDisphelper / COMate

Beitrag von jear »

Hallo Falko,

in dieser Testkonfiguration ist davon ausgegangen, dass die Dateien alle in einem Verzeichnis mit der Quelle liegen.
Außerdem ist die Option in der IDE (bei mir jaPBe) gesetzt, das Compilat im Quellverzeichnis anzulegen.

Offenbar ist COMate mit Excel sehr empfindlich. Der Pfad zu den Dateien muss absolut angegeben werden.

jear
Man ist nie zu alt zum lernen, auch wenn man dabei manchmal alt aussieht!
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Re: ExcelFunktionen PureDisphelper / COMate

Beitrag von Falko »

Da du dort home als Variable hast, ist das Verzeichnis auch korrekt vorhanden.
Somit brauche ich das nicht extra eingeben. Doch leider kann mein Excel die Test.xls, die ich erstellt habe und
auch im gleichen Verzeichnis liegt, nicht öffnen. Ich habe home weggelassen, Test.xls und Test.cbs mit dem Verzeichnis hinzugefügt, als auch mit home+ vorgegeben. Bei beiden Fehlermeldungen werden die Verzeichnisse korrekt angezeigt. Da stimmt was anderes nicht, was mir sagt, dass das Excelbook nicht geöffnent werden könne.

Gruß Falko
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
Benutzeravatar
jear
Beiträge: 288
Registriert: 17.10.2004 01:59
Wohnort: Ammerland

Re: ExcelFunktionen PureDisphelper / COMate

Beitrag von jear »

Hallo Falko,

danke, dass Du Dich überhaupt um mein Problem bemühst. <)
Die von mir verwendete Test.xls liegt http://www.kayhausen.de/PB/Test.xls (16 KB)

Ich habe nun den Code noch testfreundlicher gemacht.
Er tut in den meisten Fällen exakt was ich will.
Nur bei einigen "echten" Tabellen bleibt eine Instanz von Excel im Speicher.

Das Problem ist im Netz öfters erwähnt, alle der dort skizzierten Lösungen helfen mir aber nicht.
Das muss aber mit den verwendeten Dateien zusammenhängen, denn bei anderen Dateien klappt es ja.

Mich wundert allerdings, dass xlObj\Release keine Meldung zurückgibt. Ist das so normal?

Kann man die ProcessID des per COMate angelegten Objektes ermitteln?

Gruß aus dem Ammerland

Code: Alles auswählen

;/ jear * Nov 2009 * ExcelSheet SaveAs

IncludePath "..\"
XIncludeFile "COMatePLUS.pbi"

;/ Excel FileFormat Constants
#xlNormal = -4143
#xlSYLK = 2
#xlCSV = 6
#xlCSVMac = 22
#xlCSVMSDOS = 24
#xlCSVWindows = 23
#xlText = -4158
#xlTextMac = 19
#xlTextMSDOS = 21

Procedure.s ExcelSheetSaveAs(Origin.s, Copy.s, FileFormat.l=#xlNormal, SheetNumber.l=1)
  Protected xlObj.COMateObject, xlBook.COMateObject, xlSheet.COMateObject
  Protected result.s, args.s , WBName.s
  If FileSize(Copy) > 0 : DeleteFile(Copy) : Delay(50) : EndIf
  xlObj = COMate_CreateObject("Excel.Application")
  If COMate_GetLastErrorCode() = #S_OK
    xlObj\SetProperty("Visible = #False")
    xlObj\SetProperty("DisplayAlerts = #False") 
    xlBook = xlObj\GetObjectProperty("Workbooks\Open('" + Origin + "')") 
    If COMate_GetLastErrorCode() = #S_OK
      xlBook\Invoke("Activate()") 
      xlSheet = xlBook\GetObjectProperty("Sheets(" + Str(SheetNumber) + ")")
      If COMate_GetLastErrorCode() = #S_OK
        xlSheet\Invoke("Activate()") 
        args = "SaveAs('" + Copy + "'," + Str(FileFormat) + ")" : xlBook\Invoke(args)
        If COMate_GetLastErrorCode() = #S_OK
          result + #lf$ + args 
          xlBook\SetProperty("Saved = #True")  
          xlBook\Invoke("Close") : result + #lf$ +  "xlBook\ Close : " + COMate_GetLastErrorDescription()
          xlObj\Invoke("Quit()") : result + #lf$ +  "xlObj\ Quit : " + COMate_GetLastErrorDescription() 
        Else
          result = "ERROR: " + COMate_GetLastErrorDescription() + " (" + args + ")"
        EndIf 
        xlSheet\Release() : result + #lf$ +  "Sheet\Release : " + COMate_GetLastErrorDescription()
      Else 
        result = "ERROR: Sheet Nr. " + Str(SheetNumber) + " does not exist"
      EndIf
      xlBook\Release() : result + #lf$ +  "Book\Release : " + COMate_GetLastErrorDescription()
    Else
      result = "ERROR: Cannot open EXCEL book" + Origin 
    EndIf 
    xlObj\Release()  : result + #lf$ +  "xlObj\Release : " + COMate_GetLastErrorDescription()
  Else
    result = "ERROR: Cannot open EXCEL application" 
  EndIf  
  ProcedureReturn result
EndProcedure

;/Test

SetCurrentDirectory(GetPathPart(ProgramFilename()))
Define.s home = GetCurrentDirectory(), result

;/ Download http://www.kayhausen.de/PB/Test.xls

;result = ExcelSheetSaveAs(home + "Test.xls", home + "Test2.xls", #xlNormal, 1)
;result = ExcelSheetSaveAs(home + "Test.xls", home + "Test.slk", #xlSYLK, 1)
result = ExcelSheetSaveAs(home + "Test.xls", home + "Test.csv", #xlCSV, 3)

If result : MessageRequester("ExcelSheetSaveAs", result, #MB_OK|#MB_ICONWARNING) : EndIf

End
Man ist nie zu alt zum lernen, auch wenn man dabei manchmal alt aussieht!
ThoPie
Beiträge: 130
Registriert: 19.05.2006 15:18
Kontaktdaten:

Re: ExcelFunktionen PureDisphelper / COMate

Beitrag von ThoPie »

Hallo,

ich arbeite an einem PureBasic-Projekt in welchem Excel-Dateien, unter Verwendung dieses tollen Includes, erstellt werden. Ich möchte nun Spaltenbreiten ändern. Kann mir bitte jemand einen Tipp geben. Ich bräuchte also eine Funktion wie

Code: Alles auswählen

Procedure SetColumnWidth()
Vielen Dank.
Bild
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Re: ExcelFunktionen PureDisphelper / COMate

Beitrag von Falko »

ThoPie hat geschrieben:Hallo,

ich arbeite an einem PureBasic-Projekt in welchem Excel-Dateien, unter Verwendung dieses tollen Includes, erstellt werden. Ich möchte nun Spaltenbreiten ändern. Kann mir bitte jemand einen Tipp geben. Ich bräuchte also eine Funktion wie

Code: Alles auswählen

Procedure SetColumnWidth()
Vielen Dank.

Hier ein Beispiel dazu:

Code: Alles auswählen

Procedure SetColumnWidht(ExcelObject.COMateObject, Range.s,Width.f); Range kann sein A oder A:A usw. Widht ist die Spaltenbreite
  ExcelObject\Invoke("Columns('"+Range+"')\Select")
  ExcelObject\SetProperty("Selection\ColumnWidth="+Str(Width))
EndProcedure
;....

;Verschiedenen Aufrufmöglichkeiten:
SetColumnWidht(ExcelObject,"D", 5)
;oder
SetColumnWidht(ExcelObject,"D:D", 5)
;oder
SetColumnWidht(ExcelObject,"A:C", 10.2)

;....

Ich hab's oben in der Include-pbi sowie im Beispielsource eingebaut.

Gruß Falko
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
ThoPie
Beiträge: 130
Registriert: 19.05.2006 15:18
Kontaktdaten:

Re: ExcelFunktionen PureDisphelper / COMate

Beitrag von ThoPie »

Danke Falko.
Fallst du noch was auf Lager hast, um die Include zu erweitern ... immer her damit. ;-)
Bild
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Re: ExcelFunktionen PureDisphelper / COMate

Beitrag von Falko »

ThoPie hat geschrieben:Danke Falko.
Fallst du noch was auf Lager hast, um die Include zu erweitern ... immer her damit. ;-)
Da man nicht nur Spaltengrößen verändern möchte hätte ich hier auch noch was für die Zeilen :wink:

Code: Alles auswählen

Procedure SetRowsHeight(ExcelObject.COMateObject, Range.s,Height.f); Set Height on rang to rows
  ExcelObject\Invoke("Rows('"+Range+"')\Select")
  ExcelObject\SetProperty("Selection\RowHeight="+Str(Height))
EndProcedure

Procedure SetRowHeight(ExcelObject.COMateObject, Range.s,Height.f); Set Height to one or all Rows
  ExcelObject\Invoke("Row('"+Range+"')\Select")
  ExcelObject\SetProperty("Selection\RowHeight="+Str(Height))
EndProcedure
Ich baue sie dann gleich mal in die Include mit den angepassten Demo-Beispiel ein,
wobei ich aber universeller nur das SetRowsHeight() benutze. Beim normalen SetRowHeight, kann man das gesamte Tabellenblatt mit einer festen Zeilenhöhe vorgeben, indem man einfach nur mehr als eine Zeile angibt. Darum diese zwei Funktionen.

Des weiteren habe ich SetFont() angepasst bzw. abgeändert und im Beispiel
auch mal eine Andere Schrift ausprobiert.

Nun geht das Speichern auf dem Desktop automatisch und es braucht auch zuvor kein Ordner angelegt werden, damit die Demo funktioniert.
Sollte jemand mit Excel ab 2007 damit ausprobieren wollen, wird er schnell merken, das sich diese dann nicht öffnen lässt.

Nun habe ich zum Anfang eine Messagebox eingefügt, die die korrekte Vorgabe für
Excel älter oder neuer als 2007 abfragt, womit dann der Extender korrigiert wird.


Also dann erst mal viel Spaß.

Gruß Falko
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
ThoPie
Beiträge: 130
Registriert: 19.05.2006 15:18
Kontaktdaten:

Re: ExcelFunktionen PureDisphelper / COMate

Beitrag von ThoPie »

Danke. Danke. Ich bin begeistert.
Nur weiter so.
Bild
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Re: ExcelFunktionen PureDisphelper / COMate

Beitrag von Falko »

ThoPie hat geschrieben:Danke. Danke. Ich bin begeistert.
Nur weiter so.
Hier habe ich mal was ausprobiert um ein Kommentar für eine Zelle einzufügen.
Nur leider komme ich nur bis zum Namen, aber nicht dem Kommentar. Vermutlich
mag COMatePlus das nicht so wie VBA das haben will.

Code: Alles auswählen

Procedure AddComment(ExcelObject.COMateObject, Range.s, Name.s, MyComment.s); write comments to cells
  ExcelObject\Invoke("Range('"+Range+"')\AddComment")
  ExcelObject\Setproperty("Range('"+Range+"')\Comment\Visible = False")
  ExcelObject\Setproperty("Range('"+Range+"')\Comment\Text Text:= '"+Name+"' & Chr(10) & '"+MyComment+"'")
EndProcedure

AddComment(ExcelObject,"B5","Falko","Hier mein Kommentar")
@all
Falls ihr hierfür eine passende Lösung habt, wäre ich euch sehr dankbar. Man könnte
das Visible zusätzlich in den Parametern einbinden, sodass auch die Variable True angegeben werden kann um den Kommentar dauerhaft anzuzeigen.

Gruß Falko
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Re: ExcelFunktionen PureDisphelper / COMate

Beitrag von Falko »

Falko hat geschrieben:
ThoPie hat geschrieben:Danke. Danke. Ich bin begeistert.
Nur weiter so.
Hier habe ich mal was ausprobiert um ein Kommentar für eine Zelle einzufügen.
Nur leider komme ich nur bis zum Namen, aber nicht dem Kommentar. Vermutlich
mag COMatePlus das nicht so wie VBA das haben will.

Code: Alles auswählen

Procedure AddComment(ExcelObject.COMateObject, Range.s, Name.s, MyComment.s); write comments to cells
  ExcelObject\Invoke("Range('"+Range+"')\AddComment")
  ExcelObject\Setproperty("Range('"+Range+"')\Comment\Visible = False")
  ExcelObject\Setproperty("Range('"+Range+"')\Comment\Text Text:= '"+Name+"' & Chr(10) & '"+MyComment+"'")
EndProcedure

AddComment(ExcelObject,"B5","Falko","Hier mein Kommentar")
@all
Falls ihr hierfür eine passende Lösung habt, wäre ich euch sehr dankbar. Man könnte
das Visible zusätzlich in den Parametern einbinden, sodass auch die Variable True angegeben werden kann um den Kommentar dauerhaft anzuzeigen.

[Edit]
Nach einigen Probieren ist es mir nun gelungen ein Kommentar in die Exceltabelle auf eine
beliebige Zelle einzufügen, um diese für den Nutzer zusätzlich zu kommentieren.
Dieses erkennt man üblicherweise an dem roten Dreieck in der oberen rechten Ecke.
Zwar gibt das Makro eine andere Schreibweise vor, die ich in COMatePlus aus irgendeinen Grund leider nicht so darstellen kann. Darum habe ich das nun vereinfacht, was meinerseits ausreichend erscheint. Das Visible habe ich ebenfalls weggelassen.
Nun der funktionierende Kommentar :twisted:

Code: Alles auswählen

Procedure AddComment(ExcelObject.COMateObject, Range.s, MyComment.s); Write comments to cells
  ExcelObject\Invoke("Range('"+Range+"')\AddComment('"+MyComment+"')")
EndProcedure
Und so würde ich dann einen mehrzeiligen Kommentar einfügen:

Code: Alles auswählen

MyComment ="Das ist echt toll,"+#CRLF$
MyComment + "wenn man Kommentare"+#CRLF$
MyComment + "einfügen kann"
AddComment(ExcelObject,"B12",MyComment)
[/Edit]


Gruß Falko
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
Antworten