Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Einbindung von Office-Komponenten wie Word, Excel usw.

Moderator: Moderatoren

DelUser01

Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von DelUser01 »

Hallo

ich schaffe es einfach nicht herauszufinden wie man das macht:
1. abfragen ob Excal noch geöffnet ist oder vom User geschlossen wurde. Und
2. abfragen ob die geladene Arbeitsmappe (File) noch geöffnet ist oder vom User geschlossen wurde.

Das Excel-Objekt zu erstellen, Files zu laden, mit den Feldern zu arbeiten, und das ganze wieder schließen ist nicht das Problem. Aber wenn der User eingreift stürzt mein Programm ab.

Könnt Ihr mir da bitte auf die Sprünge helfen?
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von AUGE_OHR »

Roland Gentner hat geschrieben:1. abfragen ob Excal noch geöffnet ist oder vom User geschlossen wurde. Und
2. abfragen ob die geladene Arbeitsmappe (File) noch geöffnet ist oder vom User geschlossen wurde.
zu 1.) du kannst die Tasklist abfragen

Code: Alles auswählen

   aTasklist := GetTaskList( oDlg:gethWnd( ) )
   FOR i = 1 TO LEN( aTasklist )
       IF "Excel." $ aTasklist[i]
           //
       ENDIF  
   NEXT

FUNCTION gettasklist( hWnd )
   LOCAL aList       := {}
   LOCAL cWindowName
   LOCAL nVisible
   DO WHILE hWnd != 0
      cWindowname := SPACE( 100 )
      IF ( getwindowtexta( hWnd, @cWindowName, LEN( cWindowName ) ) <> 0 )
         nVisible := IsWindowVisible( hWnd )
         IF nVisible == 1
            AADD( aList, STR( hWnd, 8 ) + cWindowname )
         ENDIF
      ENDIF
      hWnd = GetWindow( hWnd, GW_HWNDNEXT )
   ENDDO
RETURN aList

FUNCTION GetWindow( hWnd, uCmd )
   LOCAL nDll := DllLoad( "USER32.DLL" )
   LOCAL xRet := DllCall( nDll, DLL_STDCALL, "GetWindow", hWnd, uCmd )
   DllUnLoad( nDll )
RETURN xRet

FUNCTION GetWindowTextA( hWnd, lPstring, nMax )
   LOCAL nDll := DllLoad( "USER32.DLL" )
   LOCAL xRet := DllCall( nDll, DLL_STDCALL, "GetWindowTextA", hWnd, @lPstring, nMax )
   DllUnLoad( nDll )
RETURN xRet
zu 2.) versuche doch ob du die XLS Datei mit FOPEN() "Exklusive" öffnen kannst.
gruss by OHR
Jimmy
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2821
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 94 Mal
Danksagung erhalten: 13 Mal

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von georg »

Hallo, Roland -


Du kannst das ganze aber auch "unsichtbar" ablaufen lassen, dann sind Benutzereingriffe schon schwieriger.

Ansonsten gefallen mir Jimmys Vorschläge aber auch.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von brandelh »

Am sichersten und schnellsten ist es das Excel Objekt unsichtbar zu bedienen.

Bei der Version mit der Abfrage ob ein Fenster offen ist, muss man bei Excel und vielen anderen Programmen die Titel jeweils abfragen, da diese auch von der geöffneten Datei abhängen !
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9343
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 358 Mal
Kontaktdaten:

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von Tom »

Die möglichen Problemsituationen sind ziemlich komplex. Sehr originell wird es, wenn eine Trialversion von Excel installiert ist. Dann lässt sich das Objekt zwar initialisieren, aber nicht steuern, weil Excel tatsächlich gerade die Frage stellen möchte, ob der Trial fortgesetzt werden oder das Produkt lizenziert werden soll.

Ich kann nur empfehlen, den gesamten Export- und Steuerungsprozess in eine Sequenz einzubinden. Nur auf diese Weise ist man gegen mögliche Laufzeitfehler gefeit.

Ob eine bestimme Excel-Tabelle bereits geöffnet ist, lässt sich z.B. dadurch ermitteln, dass man die Existenz der Temporärdatei abfragt, die Office grundsätzlich anlegt, wenn ein Word-Dokument, eine Excel-Tabelle oder eine Access-Datenbank geöffnet werden (Excel: ~$<DateiName>). Das ist aber nicht unbedingt verlässlich, weil die Datei - die übrigens den Namen des Nutzers enthält, der das Dokument verwendet - möglicherweise nicht gelöscht worden ist, als Excel beendet wurde. Man kann auch einfach prüfen, ob sich die Datei "shared" öffnen lässt:

(Beispiel aus Roger Donnays eXpress++-Forum)

Code: Alles auswählen

FUNCTION IsFileOpened( cFileName )

#include "fileio.ch"
LOCAL lStatus := .t.
LOCAL nHandle := FOpen( cFileName, FO_READWRITE+FO_DENYWRITE) )

IF nHandle <= 0
  DCMSGBOX 'Datei '+cFileName+' ist in Benutzung!'
  lStatus := .f.
ELSE
  FClose(nHandle)
ENDIF

RETURN lStatus
Herzlich,
Tom
DelUser01

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von DelUser01 »

Hallo Jimmy
AUGE_OHR hat geschrieben:du kannst die Tasklist abfragen
Wenn ich die Taskliste abfrage und ein "Excel.exe" gefunden wird heißt das aber nicht dass es das von mir geöffnete Excel-Objekt ist. Der User kann mehrere Excel-Objekte und auch manuell gestartetes Excel geöffnet haben (ist sogar anzunehmen).
AUGE_OHR hat geschrieben:versuche doch ob du die XLS Datei mit FOPEN() "Exklusive" öffnen kannst
Das mache ich schon. Die Abfrage müsste zur Sicherheit vor jedem Excel-Zugriff erfolgen (weiß nicht ob das Gut ist). Und das wäre für das Netzwerk ganz schön belastend. Langsam wäre es vermutlich auch noch.
Beim Testen ist das Programm trotzdem immer wieder abgestürzt. Die FOpen()-Abfrage ist vermutlich zu träge wenn der User [X] anklickt.
DelUser01

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von DelUser01 »

Hallo Georg
georg hat geschrieben:Du kannst das ganze aber auch "unsichtbar" ablaufen lassen, dann sind Benutzereingriffe schon schwieriger
Das geht in diesem Fall nicht. Der Benutzer aktiviert das entsprechende Arbeitsblatt und
positioniert den Cursor. Dann werden automatisch Werte eingetragen wenn im Excel-Sheet noch keine stehen.

Wenn das mit der Abfrage "ob Excel und das Sheet noch geöffnet sind" nicht sauber funktioniert kann ich nur die Automatik abschalten und der User muss jeweils "Start" anklicken (oder so).

Selbst mir passiert es beim Ausarbeiten und Testen immer wieder dass ich Excel mit [X] zumache statt über die Xbase++ App.

@Jimmy:
Ohne permanente Kommunikation mit dem Excel-Objekt reicht FOpen() vollkommen in einer Schleife abzufragen.
DelUser01

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von DelUser01 »

Hallo Hubert
brandelh hat geschrieben:...die Titel jeweils abfragen
OK - an das habe ich nicht gedacht, dass wäre bei der Prozessabfrage noch eine Möglichkeit festzustellen ob auch noch das richtige Fenster geöffnet/vorhanden ist.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von brandelh »

Warum muss dein Anwender bestimmen wohin die Daten sollen ?

Wenn irgend möglich, sollte das dein Programm ermitteln und seinen Job machen.
Wenn ER das tatsächlich muss, dann würde ich so vorgehen:

1. Excel anzeigen mit dem Hinweis den Cursor zu positionieren ... natürlich sichtbar
2. In deiner Anwendung den "Starte Übergabe" Button drücken.
3. Nun schaltet deine Anwendung das Excel Objekt auf unsichtbar (das geht !)
4. Werte übertragen
5. Excel Objekt wieder sichtbar machen und Erfolgsmeldung ausgeben.
Gruß
Hubert
DelUser01

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von DelUser01 »

Hallo Hubert

das mit dem "Start => unsichtbar machen" würde natürlich gehen. Der User hat aber insbesondere bei einer Neuanlage des Kalkulationsblattes mehreres auszufüllen. D.h. das Blatt muss wieder sichtbar werden für die nächste Position usw.

Es gäbe hier natürlich die Möglichkeit den Ablauf anders aufzubauen, indem der User die Einzutragenden Positionen über eine Xbase++-Liste auswählt und erst wenn alles fertig ist wird das Sheet angezeigt.

Nichts desto trotz ist bei einem permanenten Info-Austausch zwischen Xbase++ und dem Excel-Objekt die Ermittlung des Objekt-Status unabdingbar.
DelUser01

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von DelUser01 »

Habe die Prüfung ob das Excel-Sheet noch geöffnet ist gerade so gelöst:

Code: Alles auswählen

Function ExcelTestIfBookIsOK1( oBook )
Local lObjOK := .F.
Local oSheets
Local nSheets
* Break hier setzen
Begin Sequence
   oSheets := oBook:Sheets
   nSheets := oSheets:Count
   lObjOK   := .T.
End Sequence
* Break zurücksetzen
Return( lObjOk )
Die Sheet-Abfrage scheint "verlässlich" einen Error zu produzieren wenn keine Arbeitsmappe geladen ist (File).

Eine "verlässliche" Prüfung ob das Excel-Objekt noch mit Excel.exe verbunden ist habe ich noch nicht gefunden.
oExcel:Visible scheint immer zu antworten,
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von brandelh »

Wenn möglich würde ich alle Werte in einem Xbase Fenster abfragen und auf einmal in Excel eintragen ... möglichst das Ziel errechnen.

Es ist eine Weile her, aber ich mache das so:

VOR der Excel-Datenübergabe oExcel:visible := .F. // das Fenster wird versteckt, der Anwender kann nicht mehr stören
NACH der Excel-Datenübergabe oExcel:visible := .T. // zeigt das Fenster wieder an, der Anwender kann prüfen, neue Position bestimmen etc.

Das Programm kann immer hin und herschalten !
Gruß
Hubert
DelUser01

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von DelUser01 »

Hubert, so wie Du schreibst soll es ja auch gemacht werden.
Nur wenn der User Excel schließt sollen auch automatisch alle Excel-Funktionen in meinem Programm deaktiviert werden.

Da ich das (noch) nicht herausgefunden habe wie man das erkennt dass der User Excel beendet hat "hänge" ich das im Moment an die Überprüfung ob die Arbeitsmappe noch geladen ist. Wenn nicht dann schließe ich auch das Excel-Objekt.

Hier ein Text zu diesem Thema von MS, hat mich aber (noch) nicht schlauer gemacht:
http://support.microsoft.com/kb/192348/de

Ergänzung:
laut dem o.g. MS-Text scheint es wirklich nur über die Methode "den Fenstertext finden" zu gehen (=> Hubert).
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von brandelh »

OK, was passiert wenn der Anwender Excel schließt und du auf das Excel Objekt zugreifst ?

Erhälst du einen Laufzeitfehler ? Wenn ja, dann könntest du die Fehlerbehandlung so ändern, dass dieser Laufzeitfehler ignoriert wird und deine Excel Routine endet.
Da ich meinen Ablauf nur selbst bediene und "Narrensicher" gemacht habe, kommt das bei mir nicht vor.
Gruß
Hubert
DelUser01

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von DelUser01 »

Hallo Herbert

das ist ja der Springende Punkt: alles nur weil der User geführt werden muss und möglichst früh nicht "ordnungsgemäße" Vorgehensweisen erkannt werden sollten.

Laufzeitfehler:
Wenn eine Arbeitsmappe in Excel geöffnet ist kann alles mögliche abgefragt und getan werden. Ist keine Mappe geöffnet (User hat die geschlossen) kommt es beim Zugriff auf oBook usw. zu Laufzeitfehlern. das lässt sich abfangen.

Man kann die Mappe neu laden wenn der User diese geschlossen hat.
Das geht seltsamer Weise auch wenn der User Excel bereits geschlossen hat - also eigentlich das Excel-Objekt eigentlich nicht mehr verwendbar sein sollte. Dann geht Excel erneut auf! Ohne vorherige Anforderung eines neuen Automation-Objekts.

Das ist alles sehr seltsam...
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von brandelh »

Roland Gentner hat geschrieben:Das geht seltsamer Weise auch wenn der User Excel bereits geschlossen hat - also eigentlich das Excel-Objekt eigentlich nicht mehr verwendbar sein sollte.
Dann geht Excel erneut auf! Ohne vorherige Anforderung eines neuen Automation-Objekts.
Das ist alles sehr seltsam...
Nö das ist logisch, denn obwohl die sichtbare Arbeitsmappe beendet wird, bleibt der Servertask von Excel aktiv und wird solange nicht beendet, bis Xbase++ seine Resourcen freigibt.
Gruß
Hubert
DelUser01

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von DelUser01 »

brandelh hat geschrieben:...bleibt der Servertask von Excel aktiv und wird solange nicht beendet, bis Xbase++ seine Resourcen freigibt.
Das passiert wenn das Automation-Objekt auf NIL gesetzt wird?
Und vermutlich beim Verlassen der Xbase++-App.

Deshalb interessiert mich ja schlussendlich der Excel-Objektstatus um diesen sauber abschließen zu können.

Das bringt mich zu der Frage:
wenn ich mehrere Arbeitsmappen aufmache, ist das dann immer dasselbe Excel-Objekt oder wird mit CreateObject() jedes Mal ein neues Objekt erstellt?
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von brandelh »

Wenn es ein Objekt wäre, würden die sich gegenseitig stören !
Gruß
Hubert
DelUser01

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von DelUser01 »

OK - also nur ein Excel-Objekt.

Hast Recht - würde mit den Arbeitsmappen nur Ärger geben.

Und wird beim Verlassen der Xbase++-App auch nicht automatisch gelöscht (gerade aufgefallen).
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1991
Registriert: Do, 14. Aug 2008 0:22
Wohnort: Gmunden am Traunsee, Österreich
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von Herbert »

brandelh hat geschrieben:
Roland Gentner hat geschrieben:Das geht seltsamer Weise auch wenn der User Excel bereits geschlossen hat - also eigentlich das Excel-Objekt eigentlich nicht mehr verwendbar sein sollte.
Dann geht Excel erneut auf! Ohne vorherige Anforderung eines neuen Automation-Objekts.
Das ist alles sehr seltsam...
Nö das ist logisch, denn obwohl die sichtbare Arbeitsmappe beendet wird, bleibt der Servertask von Excel aktiv und wird solange nicht beendet, bis Xbase++ seine Resourcen freigibt.
Das sind sehr heikle Fragen. Es kann sein, dass der Anwender vor Programmaufruf bereits ein Excel selber geöffnet hat. Schiesst du nun aus der Applikation heraus das Excel ab, so zerstörst du auch das vorgängig durch den User geöffnete Sheet, was nicht gerade freundschaftlich wäre.
Daher zuerst nachsehen (Jimmy hat's gezeigt), ob Excel bereits läuft. Anchliessend nur noch Shetts öffnen und schliessen.
Grüsse Herbert
Immer in Bewegung...
DelUser01

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von DelUser01 »

Hallo Herbert
Herbert hat geschrieben:Es kann sein, dass der Anwender vor Programmaufruf bereits ein Excel selber geöffnet hat. Schiesst du nun aus der Applikation heraus das Excel ab, so zerstörst du auch das vorgängig durch den User geöffnete Sheet
Habe das gerade getestet:
- Excel geöffnet und eine Arbeitsmappe geladen,
- Xbase++-App gestartet,
- CreateObject(),
- Arbeitsmappe laden -> neues Excel-Fenster erscheint,
- Arbeitsmappe und Excel schließen,
=> das zuvor bereits geöffnete Excel-Fenster und die Arbeitsmappe bleiben weiter geöffnet.
=> wird die selbe Arbeitsmappe geöffnet ist die im 2. Fenster schreibgeschützt.

Also erst einmal nicht ganz so kritisch...
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1991
Registriert: Do, 14. Aug 2008 0:22
Wohnort: Gmunden am Traunsee, Österreich
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von Herbert »

Was passiert, wenn du dein Programm schliesst? Bleibt Excel offen?
Grüsse Herbert
Immer in Bewegung...
DelUser01

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von DelUser01 »

Hallo Herbert

wird die Xbase++-App geschlossen bleibt alles geöffnet, Excel + Mappe(n).
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von Koverhage »

oBook:BeforeClose := {||lExcelFinished := .T.}
lExcelFinished := .F.

oExcel:Interactive := .T.


Do WHILE !lExcelFinished
// Just wait
nEvent := AppEvent( @mp1, @mp2, , 1)
EndDo
endif

// Quit Excel
oExcel:Quit()
sleep(100)
oExcel:Destroy()
oExcel := NIL
Gruß
Klaus
DelUser01

Re: Excel-Object: Excel geöffnet? Arbeitsblatt geladen?

Beitrag von DelUser01 »

Hallo Klaus

das mit o:BeforeClose() werde ich probieren...
Antworten