[gelöst] Prüfung ob zu öffnendes Dokument bereits geöffnet ist
Moderator: Moderatoren
[gelöst] Prüfung ob zu öffnendes Dokument bereits geöffnet ist
Hallo,
ich habe ein Quell- und ein Zieldokument und übertrage Bereiche von der Quelle zum Ziel. Wenn das Zeildokument geschlossen ist funktioniert das gut. Ist das Zeildokument allerdings bereits geöffnet wird es schreibgeschützt noch einmal geöffnet was natürlich das Makro zum Anstirz bringt.
Wie kann ich im Makro vor dem Öffnen prüfen ob das Ziel bereits offen ist?
ich habe ein Quell- und ein Zieldokument und übertrage Bereiche von der Quelle zum Ziel. Wenn das Zeildokument geschlossen ist funktioniert das gut. Ist das Zeildokument allerdings bereits geöffnet wird es schreibgeschützt noch einmal geöffnet was natürlich das Makro zum Anstirz bringt.
Wie kann ich im Makro vor dem Öffnen prüfen ob das Ziel bereits offen ist?
Zuletzt geändert von kilix am Sa, 29.07.2023 18:12, insgesamt 1-mal geändert.
Grüße
kilix
kilix
Re: Prüfung ob zu öffnendes Dokument bereits geöffnet ist
Ich habe das Problem jetzt mit einem Workaround umgangen da ich verhindern möchte, dass das Makro abstürzt. Durch das Öffnen von Test.ods wird Test.ods geöffnet - auch wenn es bereits geöffnet war - allerdings schreibgeschützt. Daher kann der folgende Befehl: speichern eines Bereichs nicht durchgeführt werden und das Makro stürzt mit Fehler ab.
Daher habe ich den Fehler mit On Error abgefangen und in einer Fehlerroutine verzweigt, die eine Fehlermeldung bringt und die schreibgeschützt geöffnete Datei wieder schließt. Damit wird er Anwender aufgefordert die bereits geöffnete DAtei Test,ods zu schließen und das Makro neu zu starten.
Schöner wäre es natürlich ich könnte bereits im Vorhinein feststellen, dass die Datei Test.ods bereits geöffnet ist. Dann könnte ich mit dieser Datei weiterarbeiten. Leider habe ich dafür keine Lösung gefunden.
Daher habe ich den Fehler mit On Error abgefangen und in einer Fehlerroutine verzweigt, die eine Fehlermeldung bringt und die schreibgeschützt geöffnete Datei wieder schließt. Damit wird er Anwender aufgefordert die bereits geöffnete DAtei Test,ods zu schließen und das Makro neu zu starten.
Code: Alles auswählen
Sub Test
oDoc=ThisComponent
surl = oDoc.url
apfad = split(surl,"/")
apfad(ubound(apfad)) = "test.ods"
sURL = convertToURL(join(apfad,"/"))
dim myFileProp() as new com.sun.star.beans.PropertyValue
On Error Goto FehlerRoutine:
oODS = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, myFileProp())
'1. Auslesen der Testdaten in Tab: Auswahl
aDaten = oDoc.Sheets(2).getCellRangeByName("A3:C10003").getDataArray
'Schreiben der Daten in die aktuelle Datei
oODS.Sheets(1).getCellRangeByName("A3:C10003").setDataArray(aDaten)
.
.
usw
.
.
oODS.unlockcontrollers
oODS.store()
oODS.close(false)
Exit Sub
FehlerRoutine:
MsgBox("Die Datei Test.ods ist bereits geöffnet" + CHR(13) +_
"Schließen sie diese Datei und starten sie das Makro neu")
oODS.close(false) 'schließen der schreibgeschützt geöffneten Test.ods
End Sub
Grüße
kilix
kilix
Re: Prüfung ob zu öffnendes Dokument bereits geöffnet ist
Hallo,
auf direktem Weg ist das nicht möglich. Es gibt aber folgenden Weg:
Alle geöffneten Fenster (also Dateien, Hilfe, IDE, ...) sind als Komponenten des Stardesktops gelistet. Die kann man durchsuchen, ob die gewünschte dabei ist. Eine ähnliche Funktion findest du hier:
http://www.dannenhoefer.de/faqstarbasic ... terwaehlen
auf direktem Weg ist das nicht möglich. Es gibt aber folgenden Weg:
Alle geöffneten Fenster (also Dateien, Hilfe, IDE, ...) sind als Komponenten des Stardesktops gelistet. Die kann man durchsuchen, ob die gewünschte dabei ist. Eine ähnliche Funktion findest du hier:
http://www.dannenhoefer.de/faqstarbasic ... terwaehlen
Gruß,
mikeleb
mikeleb
Re: Prüfung ob zu öffnendes Dokument bereits geöffnet ist
Hallo mikeleb,
danke für die Antwort. Genau in diesem Dokument habe ich ich schon etwas gefunden.
Soweit ich es verstanden habe werden hier die die geöffneten Dateien durchsucht und geprüft ob die gesuchte dabei ist (ich habe den Code leicht modifiziert). In diesem Code kommt exakt die gleiche Zeile wie in dem von dir kopierten Code vor
FileN=FileNameoutofPath(datei)
Genau in dieser Zeile stürzt die Sub mit der Meldung: "Basic-Laufzeitfehler, Sub- oder Function-Procedur nicht definiert."
Dannenhöfer schreibt: "Dies geht mit FileNameoutofPath aus der Bibliothek Tools."
Er hat in seinem Dokument einen Abschnitt mit Tools aber dort habe ich nichts passendes gefunden. Ich weiß auch nicht wo es diese Bibliothek Tools gibt.
Ein weiteres Problem ist, dass ich wenn ich die Datei als geöffnet identifiziert habe nur eine Meldung sinden kann, die dem Anwender sagt, schließe zuerst diese Datei und starte das Makro neu. Das Widersinnige dabei ist, dass das Makro genau diese Datei dann selbst öffnet. Für mich logischer wäre es, wenn ich die URL schone kenne und weiß, dass diese Datei geöffnet ist, die gleich zu verwenden und dazu habe ich nichts gefunden. Ich weiß zwar wie man mit einer bekannten URL eine Datei öffnen kann
(oODS = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, myFileProp())
aber nicht wie ich die Variable oODS (in diesem Beispiel) bei einer bereits geöffneten Datei befüllen kann. Könnte ich das dann bräuchte ich keine Fehlermeldung und könnte die gesammte Verarbeitung durchführen, egal ob die Datei zu öffnen ist oder die bereits geöffnete verwendet wird.
danke für die Antwort. Genau in diesem Dokument habe ich ich schon etwas gefunden.
Code: Alles auswählen
Sub Datei_suchen
GesuchteDatei="einritte.ods"
Dim oDesktop As Object, oDocs As Object
Dim oDoc As Object, oComponents As Object
oComponents = StarDesktop.getComponents()
oDocs = oComponents.createEnumeration()
Do While oDocs.hasMoreElements()
oDoc = oDocs.nextElement()
datei=odoc.geturl()
FileN=FileNameoutofPath(datei)
if FileN=GesuchteDatei then
print "gefunden"
End If
Loop
End sub
FileN=FileNameoutofPath(datei)
Genau in dieser Zeile stürzt die Sub mit der Meldung: "Basic-Laufzeitfehler, Sub- oder Function-Procedur nicht definiert."
Dannenhöfer schreibt: "Dies geht mit FileNameoutofPath aus der Bibliothek Tools."
Er hat in seinem Dokument einen Abschnitt mit Tools aber dort habe ich nichts passendes gefunden. Ich weiß auch nicht wo es diese Bibliothek Tools gibt.
Ein weiteres Problem ist, dass ich wenn ich die Datei als geöffnet identifiziert habe nur eine Meldung sinden kann, die dem Anwender sagt, schließe zuerst diese Datei und starte das Makro neu. Das Widersinnige dabei ist, dass das Makro genau diese Datei dann selbst öffnet. Für mich logischer wäre es, wenn ich die URL schone kenne und weiß, dass diese Datei geöffnet ist, die gleich zu verwenden und dazu habe ich nichts gefunden. Ich weiß zwar wie man mit einer bekannten URL eine Datei öffnen kann
(oODS = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, myFileProp())
aber nicht wie ich die Variable oODS (in diesem Beispiel) bei einer bereits geöffneten Datei befüllen kann. Könnte ich das dann bräuchte ich keine Fehlermeldung und könnte die gesammte Verarbeitung durchführen, egal ob die Datei zu öffnen ist oder die bereits geöffnete verwendet wird.
Grüße
kilix
kilix
Re: Prüfung ob zu öffnendes Dokument bereits geöffnet ist
Hallo,
es gibt so ein paar Hürden zu überwinden, die manchmal nicht so offensichtlich sind:
1) Die Prozedur FileNameoutofPath extrahiert den Dateinamen aus der URL. Diese Prozedur ist in der mitgelieferten Bibliothek Tools enthalten. Um darauf zuzugreifen, muss diese Bibliothek am Anfang deines Makros geladen werden:
Nun kannst du alle Prozeduren dieser Bibliothek nutzen.
2) Nicht jedes Element von StarDesktop.getComponents() besitzt die Methode .getUrl. In dem Fall würde es einen Abbruch des Makros geben.
3) Der Dateiname definiert das Fenster nicht eindeutig. Im Gegensatz zu MS Office können mehrere Dateien mit dem Namen test.ods geöffnet sein, wenn sie in verschiedenen Verzeichnissen liegen.
Der Dateiname taucht zwar im Titel des Fensters auf. Er muss es aber nicht. Ungespeicherte Dateien haben eine leere Url, heißen im Fenster aber z. B."Unbenannt1.ods"
Mit den Vorbemerkungen schlage ich folgendes Makro vor:
es gibt so ein paar Hürden zu überwinden, die manchmal nicht so offensichtlich sind:
1) Die Prozedur FileNameoutofPath extrahiert den Dateinamen aus der URL. Diese Prozedur ist in der mitgelieferten Bibliothek Tools enthalten. Um darauf zuzugreifen, muss diese Bibliothek am Anfang deines Makros geladen werden:
Code: Alles auswählen
GlobalScope.BasicLibraries.LoadLibrary("Tools")
2) Nicht jedes Element von StarDesktop.getComponents() besitzt die Methode .getUrl. In dem Fall würde es einen Abbruch des Makros geben.
3) Der Dateiname definiert das Fenster nicht eindeutig. Im Gegensatz zu MS Office können mehrere Dateien mit dem Namen test.ods geöffnet sein, wenn sie in verschiedenen Verzeichnissen liegen.
Der Dateiname taucht zwar im Titel des Fensters auf. Er muss es aber nicht. Ungespeicherte Dateien haben eine leere Url, heißen im Fenster aber z. B."Unbenannt1.ods"
Mit den Vorbemerkungen schlage ich folgendes Makro vor:
Code: Alles auswählen
Sub Datei_suchen
Dim oDesktop As Object, oDocs As Object
Dim oDoc As Object, oComponents As Object
GlobalScope.BasicLibraries.LoadLibrary("Tools")
GesuchteDatei="einritte.ods"
oComponents = StarDesktop.getComponents()
oDocs = oComponents.createEnumeration()
gefunden=false
Do While oDocs.hasMoreElements() and gefunden=false
oDoc = oDocs.nextElement()
if odoc.supportsservice("com.sun.star.document.OfficeDocument") then
sdatei=odoc.geturl()
if sDatei<>"" then
sdateiname=FileNameoutofPath(sdatei)
end if
if sdateiname=GesuchteDatei then
gefunden=true
End If
End if
Loop
'die Schleife bricht ab, wenn alle Fenster durchlaufen wurde oder wenn die Datei gefunden wurde
'wenn die Datei gefunden wurde, referenziert die Variable oDoc auf diese Datei, ansonsten auf das letzte Fenster!
If gefunden then
msgbox "gefunden"
'nun zum Beispiel die Anzeige der kompletten Url der Datei
msgbox odoc.url
else
odoc=nothing
end if
'jetzt enthält odoc entweder die gesuchte Datei oder die Variable ist leer
End sub
Gruß,
mikeleb
mikeleb
Re: Prüfung ob zu öffnendes Dokument bereits geöffnet ist
Hallo mikeleb,
vielen DAnk für deine Sub!
Ich habe sie etwas verändert damit ich sie auf für andere Subs mit ähnlicher Aufgabe (z.B. öffnen eines anderen Dokuments) verwenden kann. Außerdem habe zwei Variable als Public definiert damit ich das Ergebnis im Makro weiterverwenden kann.
So sieht der Code jetzt aus:
vielen DAnk für deine Sub!
Ich habe sie etwas verändert damit ich sie auf für andere Subs mit ähnlicher Aufgabe (z.B. öffnen eines anderen Dokuments) verwenden kann. Außerdem habe zwei Variable als Public definiert damit ich das Ergebnis im Makro weiterverwenden kann.
So sieht der Code jetzt aus:
Code: Alles auswählen
Beginn des Makros:
Public oDoc1 as Object
Public gefunden as Boolean
Sub Einritte_erfassen
Datei_suchen("Einritte.ods")
.
.
.
End sub
Sub Datei_suchen(Dateiname) ' so kann ich auch andere Dateinamen einsetzen
Dim oDesktop As Object, oDocs As Object
' Dim oDoc1 As Object ' oDoc1 weil ich im Makro schon oDoc verwende (wäre
' wahrscheinlich nicht nötig da diese Variable nur un der Sub gilt
Dim oComponents As Object
GlobalScope.BasicLibraries.LoadLibrary("Tools")
GesuchteDatei=Dateiname
oComponents = StarDesktop.getComponents()
oDocs = oComponents.createEnumeration()
gefunden=false
Do While oDocs.hasMoreElements() and gefunden=false
oDoc1 = oDocs.nextElement()
if odoc1.supportsservice("com.sun.star.document.OfficeDocument") then
sdatei=odoc1.geturl()
if sDatei<>"" then
sdateiname=FileNameoutofPath(sdatei)
end if
if lcase(sdateiname)=lcase(GesuchteDatei) then
gefunden=true
End If
End if
Loop
'die Schleife bricht ab, wenn alle Fenster durchlaufen wurde oder wenn die Datei gefunden wurde
'wenn die Datei gefunden wurde, referenziert die Variable oDoc auf diese Datei, ansonsten auf das letzte Fenster!
If gefunden then
MsgBox ("Einritte.ods ist bereits geöffnet - mit Menü: Fenster in der Vordergrund holen")
' ich suche noch eine Möglichkeit das bereits geöffnete Dokument in den Vordergrund zu bringen.
' Vorläufig genügt dieser Hinweis
Else
odoc1=nothing
end if
'jetzt enthält odoc entweder die gesuchte Datei oder die Variable ist leer
End sub
Grüße
kilix
kilix
Re: Prüfung ob zu öffnendes Dokument bereits geöffnet ist
Hallo,
wenn du es als function nutzt, kannst du dir die public-Variablen sparen
wenn du es als function nutzt, kannst du dir die public-Variablen sparen
Code: Alles auswählen
Beginn des Makros:
Sub Einritte_erfassen
oDoc1=Datei_suchen("Einritte.ods")
'um zu testen, ob etwas gefunden wurde:
if isnull(oDoc1) ....
.
.
End sub
Function Datei_suchen(Dateiname) ' so kann ich auch andere Dateinamen einsetzen
Dim oDesktop As Object, oDocs As Object
' Dim oDoc1 As Object ' oDoc1 weil ich im Makro schon oDoc verwende (wäre
' wahrscheinlich nicht nötig da diese Variable nur un der Sub gilt
Dim oComponents As Object
GlobalScope.BasicLibraries.LoadLibrary("Tools")
GesuchteDatei=Dateiname
oComponents = StarDesktop.getComponents()
oDocs = oComponents.createEnumeration()
gefunden=false
Do While oDocs.hasMoreElements() and gefunden=false
oDoc1 = oDocs.nextElement()
if odoc1.supportsservice("com.sun.star.document.OfficeDocument") then
sdatei=odoc1.geturl()
if sDatei<>"" then
sdateiname=FileNameoutofPath(sdatei)
end if
if lcase(sdateiname)=lcase(GesuchteDatei) then
gefunden=true
End If
End if
Loop
'die Schleife bricht ab, wenn alle Fenster durchlaufen wurde oder wenn die Datei gefunden wurde
'wenn die Datei gefunden wurde, referenziert die Variable oDoc auf diese Datei, ansonsten auf das letzte Fenster!
If gefunden then
MsgBox ("Einritte.ods ist bereits geöffnet - mit Menü: Fenster in der Vordergrund holen")
' ich suche noch eine Möglichkeit das bereits geöffnete Dokument in den Vordergrund zu bringen.
' Vorläufig genügt dieser Hinweis
Else
odoc1=nothing
end if
Datei_suchen=oDoc1
End sub
Gruß,
mikeleb
mikeleb
Re: Prüfung ob zu öffnendes Dokument bereits geöffnet ist
Danke! Ich hatte schon versucht diese Sub als Funktion zu schreiben. Bin dabei aber an einem Punkt hängen geblieben. Das ist die Zeile in deinem Beispiel:
Datei_suchen=oDoc1
Das hat mir gefehlt denn ich bekam keinen Wert zurück. Bei FreeBasic würde es heißen Result = oDoc1 aber jetzt hab ich gesehen, dass du den Namen der Funktion verwendest!
Datei_suchen=oDoc1
Das hat mir gefehlt denn ich bekam keinen Wert zurück. Bei FreeBasic würde es heißen Result = oDoc1 aber jetzt hab ich gesehen, dass du den Namen der Funktion verwendest!
Grüße
kilix
kilix
Re: Prüfung ob zu öffnendes Dokument bereits geöffnet ist
Hallo,
Und am Ende muss esheißen
Und am Ende muss es
Code: Alles auswählen
end function
Gruß,
mikeleb
mikeleb
Re: Prüfung ob zu öffnendes Dokument bereits geöffnet ist
Danke. Das ist klar. So etwas übersieht man leicht 

Grüße
kilix
kilix