Excel schiesst Applikation ab

Einbindung von Office-Komponenten wie Word, Excel usw.

Moderator: Moderatoren

Antworten
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1549
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern

Excel schiesst Applikation ab

Beitrag von Werner_Bayern » Sa, 18. Feb 2012 17:09

Kann mir jemand sagen, was ich hier falsch mache? Wird der Button ausgelöst und ich bin so gemein und klicke in das Excel-Arbeitsblatt, kommt ja die Fehlermeldung aber danach geht meist gar nichts mehr, oder das Prog beendet sich.

Zum Testen bitte einfach in Zeile 60 eine beliebige DBF einsetzen, wird nicht geändert.

Code: Alles auswählen

#include "Xbp.ch"
#include "Appevent.ch"
#include "Gra.ch"
#pragma Library( "ascom10.lib" )

PROCEDURE Appsys
RETURN

PROCEDURE Main
LOCAL nEvent, mp1, mp2, oXbp
LOCAL oDlg
LOCAL oDraw

   oDlg          := XbpDialog():new( AppDesktop(),,, {200, 100} )
   oDlg:tasklist := .T.
   oDlg:titlebar := .T.
   oDlg:title    := "Excel-Test"
   oDlg:create():Show()
   centerControl(oDlg)

   oDraw := oDlg:drawingArea
   oDraw:SetcolorBG(GRA_CLR_YELLOW)

   oXbp := XbpPushbutton():new(oDraw,, {50, 10}, {80, 30})
   oXbp:caption := "Excel-Test"
   oXbp:activate := {||excel()}
   oXbp:create()


   nEvent := 0
   DO WHILE nEvent <> xbeP_Close
      nEvent := AppEvent( @mp1, @mp2, @oXbp )
      oXbp:handleEvent( nEvent, mp1, mp2 )
   ENDDO
RETURN



function Excel()
local nLine := 2, i, oExcel, oWorkbook, oSheet, nFelder, bAlterFehlerblock := ErrorBlock()


oExcel := CreateObject( "Excel.Application" )
IF Empty( oExcel )
   ConfirmBox(, "MS-Excel scheint nicht oder nicht korrekt installiert zu sein!" + chr(13) + "Fehlernr.: " + ltrim(str(ComLastError())) +;
   " Fehler: " + ComLastMessage(), , XBPMB_OK, XBPMB_CRITICAL)
   return .f.
ENDIF

ErrorBlock({|oError|Excelfehler(oError)})
begin sequence

oExcel:Application:DisplayAlerts := .F.
oExcel:Application:Workbooks:new()
oExcel:visible := .T.               // i want to see something
oWorkbook = oExcel:Workbooks:Add()  //oWorkbook besser zum Suchen
oSheet := oWorkbook:Worksheets(1)   //Referenz auf das 1. Worksheet

      select 0
      use ("d:\prg\xpp\adresse.dbf") SHARED
      if Neterr()
         break()
      endif
      oExcel:Application:Worksheets(1):name:='Adressen'

      go top
      nFelder := fcount()
      for i := 1 to nFelder
         oSheet:cells(1, i):Value := fieldname(i)
      next i

oSheet:RANGE('1:1'):Font:Bold      := .T.

oSheet:Range( "1:1" ):Interior:ColorIndex := 15

do while .not. eof()
   for i := 1 to nFelder
     oSheet:cells(nLine, i):Value  := fieldget(i)
   next i
   nLine++
   skip
enddo
dbclosearea()
//oExcel:application:workbooks(1):saveas(cFile)
//oExcel:Application:Quit()
//oExcel:Quit()

end sequence
ErrorBlock(bAlterFehlerblock)
return .t.


function excelfehler(oError)
confirmbox(,"In Excel ist folgender Fehler aufgetreten: " + oError:description + " Bei Ausführung von: " +;
oError:operation)
break()
return NIL
es grüßt euch

Werner

Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1912
Registriert: Do, 14. Aug 2008 0:22
Wohnort: Gmunden am Traunsee, Österreich
Kontaktdaten:

Re: Excel schiesst Applikation ab

Beitrag von Herbert » Sa, 18. Feb 2012 23:18

funktioniert, langsam aber problemlos.
Wo stürzt du denn ab?
Grüsse Herbert
Immer in Bewegung...

georg
Foren-Administrator
Foren-Administrator
Beiträge: 2243
Registriert: Fr, 08. Feb 2008 21:29

Re: Excel schiesst Applikation ab

Beitrag von georg » So, 19. Feb 2012 7:38

Hallo, Werner -


OA steht für Office Automation. Wenn Du in den "automatisierten" Prozess eingreifst, indem du z.B. auf eine andere Zelle klickst, kommt das System aus dem Tritt, daher gibt es die Fehlermeldung.

Der OA Prozess geht z.B. zu Zelle F8, um dort etwas einzutragen, und Du klickst auf D7, dann käme der Wert in die falsche Zelle, daher bricht OA mit einer entsprechenden Fehlermeldung ab.

Eine Alterantive ist, visible auf .F. zu setzen, so dass der OA Prozess "im Hintergrund" abläuft.

Das Ärgerliche an dem Abbruch ist jedoch, dass Excel im Hintergrund weiter geöffnet bleibt, also: Griff zum Task-Manager und erst einmal Excel schliessen.


Gruss,

Georg
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.

Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2434
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Kontaktdaten:

Re: Excel schiesst Applikation ab

Beitrag von Wolfgang Ciriack » So, 19. Feb 2012 11:01

Da das Füllen von einzelnen Zellen über die ActiveX Schnittstelle sehr langsam ist, solltest du das umstellen auf eine Range-Befüllung,
also z.B. erst alle Daten in ein Array (aMyArray), aus der Länge des Arrays die Endespalte (endsp) ermitteln und dann mit

Code: Alles auswählen

SetExcelValue("A1:"+endsp,oWorkSheet,aMyAarray)
das WorkSheet befüllen, das geht sehr schnell.
Viele Grüße
Wolfgang

Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1549
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern

Re: Excel schiesst Applikation ab

Beitrag von Werner_Bayern » So, 19. Feb 2012 14:40

Das ist mir alles klar. Jedoch warum hängt sich das Programm auf oder wird beendet, wenn ich Excel aus dem Tritt bringe? Es geht mir da ums Grundsätzliche.
Der Errorblock bringt brav seine Fehlermeldung und der Code sollte dann ja sauber nach dem end sequence fortgesetzt werden. Das tut es meist aber nicht.
Auch in einem extra Thread ausgelagert, gleiches Verhalten.
es grüßt euch

Werner

Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1549
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern

Re: Excel schiesst Applikation ab

Beitrag von Werner_Bayern » So, 19. Feb 2012 15:45

Herbert hat geschrieben:funktioniert, langsam aber problemlos.
Wo stürzt du denn ab?
Wird der Button ausgelöst und ich bin so gemein und klicke in das Excel-Arbeitsblatt
es grüßt euch

Werner

Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1549
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern

Re: Excel schiesst Applikation ab

Beitrag von Werner_Bayern » So, 19. Feb 2012 16:07

Wolfgang Ciriack hat geschrieben:

Code: Alles auswählen

SetExcelValue("A1:"+endsp,oWorkSheet,aMyAarray)
Worin liegt der Unterschied zu:

Code: Alles auswählen

oSheet:Range(ltrim(str(nLine)) + ":" + ltrim(str(nLine))):Value := aDaten
es grüßt euch

Werner

Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2434
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Kontaktdaten:

Re: Excel schiesst Applikation ab

Beitrag von Wolfgang Ciriack » So, 19. Feb 2012 18:24

Hallo Werner,
keiner. Ich bezog mich nur auf den Teil deines geposteten Codes:

Code: Alles auswählen

do while .not. eof()
   for i := 1 to nFelder
     oSheet:cells(nLine, i):Value  := fieldget(i)
   next i
   nLine++
   skip
enddo
Viele Grüße
Wolfgang

Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1549
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern

Re: Excel schiesst Applikation ab

Beitrag von Werner_Bayern » So, 19. Feb 2012 18:43

Servus Wolfgang,

Code: Alles auswählen

SetExcelValue
ist eine Funktion von Dir?

Hab mich jetzt fürs komplette "Abschalten" von Excel während des Exports entschieden und jeder Datensatz wird in ein Range als Array übergeben. Ist schon wesentlich schneller. Der obige Code war nur der erste Hack. :)
es grüßt euch

Werner

Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 14595
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Kontaktdaten:

Re: Excel schiesst Applikation ab

Beitrag von brandelh » Mo, 20. Feb 2012 8:38

Hi,

der errrorblock kann nur innerhalb von Xbase++ wirken, auf Excel hat er keinen direkten Zugriff.
Ob jetzt die Implementierung von Alaska oder Microsoft schuld sind, auf jeden Fall darf man nicht
mit der Tastatur oder der Maus "dazwischen funken", es scheint so wie ein Macrorecorder der
Tastaturanschläge durchreicht. Für mich selbst lasse ich Excel sichtbar und nehme die Finger
von Maus und Tastatur, ansonsten blende ich Excel aus, bis es fertig ist. (Bei Word genauso).
Gruß
Hubert

Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2434
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Kontaktdaten:

Re: Excel schiesst Applikation ab

Beitrag von Wolfgang Ciriack » Mo, 20. Feb 2012 15:26

Sorry Werner,
ist natürlich eine extra Funktion bei mir:

Code: Alles auswählen

static FUNCTION SetExcelValue(cRange,oWorkSheet,xValue)
LOCAL oRange
oRange := oWorkSheet:Range(cRange)
oRange:Select()
oRange:Value := xValue
oRange:Font:Name:="Arial"
oRange:Font:Size:=8
oRange := nil
RETURN nil
Viele Grüße
Wolfgang

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 11515
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: Excel schiesst Applikation ab

Beitrag von AUGE_OHR » Di, 21. Feb 2012 4:18

brandelh hat geschrieben:der errrorblock kann nur innerhalb von Xbase++ wirken, auf Excel hat er keinen direkten Zugriff.
Ob jetzt die Implementierung von Alaska oder Microsoft schuld sind, auf jeden Fall darf man nicht
mit der Tastatur oder der Maus "dazwischen funken", ...
das Wörtchen "unkontrolliert" fehlt.
sagte ich nicht schon mal das ein CreateObject() unter Xbase++ keine Events empfangen kann !

dafür wäre nun ein ActiveXObject() notwendig was XbpActiveXControl() enthält.
dummerweise kann man aber die Office Komponenten nicht mit XbpActiveXControl() aufrufen ... wer DSO-Framer kennt sieht hier vielleicht den Zusammenhang.

Events werden üblicherweise bei jedem User Eingriff erzeugt und wie schon erwähnt kann das entscheidende Unterschiede auf die Ausführung des Programm Code ausmachen.
man benötigt also Event gesteuerten Code der reagiert wenn sich ein Zustand ändert und darf nicht darauf hoffen das die letzten Property ( Werte ) noch aktuell sind.

CreateObject() unter Xbase++ sollte man deshalb nur "passive" einsetzten d.h. du sagst was es tun soll. da du aber ja weisst was es dann tun soll brauchst du keine Anzeige ( kannst ja eine Progressbar nehmen ) ... dann kann der User auch nichts verkehrt machen ;)

Events kann man mit CreateObject() nur dann mit :subscribeEvent() Abonnieren wenn man ein :dynamicCast() verwendet.
das Beispiel im Help File zeigt nur die "oberste" Ebene "Application" aber gewöhnlich arbeitet der User auf "Document" oder "Appointment" Ebene und diese Events muss man abfangen/auswerten.

ob man das allerdings mit Xbase++ activeX machen sollte ... ich verwende da lieber DispHpr ...

Preisfrage : warum ist ot4xb seit ot4xb_001_005_XXX um so vieles grösser ?
gruss by OHR
Jimmy

Antworten