Kann man den Benutzernamen in einem UserForm Label angeben, der das Dokument geöffnet hat?
Hi, ich liebe Herausforderungen und komme auch nach und nach weiter. Nun habe ich diese Funktion welche prüft, ob eine bestimmte Datei geöffnet ist:
Public Function IsFileOpen(FileName As String)
Dim filenum As Integer, errnum As Integer
On Error Resume Next
filenum = FreeFile()
Open FileName For Input Lock Read As #filenum
Close filenum
errnum = Err
On Error GoTo 0
Select Case errnum
Case 0
IsFileOpen = False
Case 70
IsFileOpen = True
Case Else
Error errnum
End Select
End Function
Mit dieser Funktion kann ich arbeiten, wenn das Dokument von wem auch immer geöffnet ist, öffnet sich eine UserForm.
Nun möchte ich gerne mit dieser Funktion ermitteln, welcher Benutzer das Dokument geöffnet hat:
Public Function LastUser(strPath As String) As String
Dim strXl As String
Dim strFlag1 As String, strflag2 As String
Dim i As Integer, j As Integer
Dim hdlFile As Long
Dim lNameLen As Byte
strFlag1 = Chr(0) & Chr(0)
strflag2 = Chr(32) & Chr(32)
hdlFile = FreeFile
Open strPath For Binary As #hdlFile
strXl = Space(LOF(hdlFile))
Get 1, , strXl
Close #hdlFile
j = InStr(1, strXl, strflag2)
#If Not VBA6 Then
'// Xl97
For i = j - 1 To 1 Step -1
If Mid(strXl, i, 1) = Chr(0) Then Exit For
Next
i = i + 1
#Else
'// Xl2000+
i = InStrRev(strXl, strFlag1, j) + Len(strFlag1)
#End If
'// IFM
lNameLen = Asc(Mid(strXl, i - 3, 1))
LastUser = Mid(strXl, i, lNameLen)
End Function
Aber das klappt nicht...
Ich habe es mit diesem Code probiert und diesen an meinen Pfad und das Dokument angepasst:
Private Sub TestVBA()
'http://www.xcelfiles.com/IsFileOpenVBA.htm
'// Just change the file to test here
Const strFileToOpen As String = "C:\Data.xls"
If IsFileOpen(strFileToOpen) Then
MsgBox strFileToOpen & " is already Open" & _
vbCrLf & "By " & LastUser(strFileToOpen), vbInformation, "File in Use"
Else
MsgBox strFileToOpen & " is not open", vbInformation
End If
End Sub
Bekomme immer Fehler 52.
Ich würde aber gerne den Benutzernamen auch später in der UserForm (anstatt einer MsgBox) im Label anzeigen, was ich ebenfalls nicht hinbekomme.
Weiß jemand, wie ich den Benutzernamen ermittel, der das Dokument geöffnet hat und ich diesen dann in den Label-Text einbauen kann? Oder geht das nicht?
Vielen herzlichen Dank im Voraus.
2 Antworten
Fehler 52 kann auch bedeuten, dass die Datei gar nicht existiert (dürfte eher nicht der Fall sein, höchstens, wenn sich ein unsichtbares Zeichen in das String hineingeschmuggelt hat) oder wenn die Dateinummer schon belegt ist (ist wegen FreeFile unmittelbar davor eigentlich ausgeschlossen, es sei denn, FreeFile läuft aus irgendeinem Grund über - mehr als 255 Dateien geöffnet)
Recherche:
https://www.google.com/search?client=firefox-b-d&q=Excel+Benutzername
Funde, die ich nachgesehen habe:
https://docs.microsoft.com/de-de/office/vba/api/excel.application.username - wohl nicht das Gesuchte
https://www.google.com/search?client=firefox-b-d&q=Excel+username+of+opened+file
https://www.mrexcel.com/board/threads/get-username-of-open-file-xlsx-pdf.1144449/ - hier wird auch Fehler 53 abgefangen, vielleicht findet sich in diesem Zusammenhang auch was zu Fehler 52
https://chandoo.org/forum/threads/return-user-name-who-has-file-open.31447/
Mein Bauchgefühl würde zu API-Aufrufen neigen - aber dazu gibt es nur Beispiele zum ScriptingHost, und der lässt sich kaum debuggen.
Zur UserForm: Gib dem Makro eine Objektvariable mit, in die du die UserForm einträgst. Darüber kannst du auf die Elemente der UserForm zugreifen.
' Im Stammbereich des Quellcodes des Moduls / der Tabelle / der Arbeitsmappe
Dim AnzeigeUserForm As UserForm
' innerhalb einer Methode - Sub oder Function
Set AnzeigeUserForm = new UserForm1
UserForm1.Show ' oder ähnlich, müsste den genauen Wortlaut ausprobieren
' innerhalb der Methode, in der eine Datei geprüft wird
AnzeigeUserForm.Label1 = gefundenerUserName
Ob man für ein Laufwerk Admin-Rechte braucht (ob Netzlaufwerk oder nicht), hängt allein vom Dateisystem ab. Damit hat VBA nichts zu tun - das ruft nur das "API" auf.
Allerdings sind bei Windows Netzlaufwerke benutzerspezifisch. Wenn ein Netzlaufwerk für den aktuellen Benutzer nicht eingerichtet ist, existiert es für ihn einfach nicht. Unabhängig davon, ob ein anderer Benutzer (Administrator oder nicht) dieses Laufwerk zur Verfügung hat.
Hi, erstmal danke. Ich habe einen Fehler herausgefunden. Problem beim Code mit dem Nutzernamen ist, dass der Dateiname der gesuchten Datei zum Teil variabel ist und ich deshalb einen Platzhalter verwende: "Dateiname_*.docx".
Bei der Prüfung ob das Dokument geöffnet wurde, funktioniert es auch. Nur beim Benutzernamen nicht.
Wenn ich den Dateinamen nun vollständig angebe, läuft die Prüfung zumindest durch:
Private Function IsFileOpen(FileName As String) As Boolean
Dim hdlFile As Long
On Error GoTo FileIsOpen:
hdlFile = FreeFile
Open FileName For Random Access Read Write Lock Read Write As hdlFile
IsFileOpen = False
Close hdlFile
Exit Function
FileIsOpen:
IsFileOpen = True
Close hdlFile
End Function
Public Function LastUser(strPath As String) As String
Dim strXl As String
Dim strFlag1 As String, strflag2 As String
Dim i As Integer, j As Integer
Dim hdlFile As Long
Dim lNameLen As Byte
strFlag1 = Chr(0) & Chr(0)
strflag2 = Chr(32) & Chr(32)
hdlFile = FreeFile
Open strPath For Binary As #hdlFile
strXl = Space(LOF(hdlFile))
Get 1, , strXl
Close #hdlFile
j = InStr(1, strXl, strflag2)
#If Not VBA6 Then
'// Xl97
For i = j - 1 To 1 Step -1
If Mid(strXl, i, 1) = Chr(0) Then Exit For
Next
i = i + 1
#Else
'// Xl2000+
i = InStrRev(strXl, strFlag1, j) + Len(strFlag1)
#End If
'// IFM
lNameLen = Asc(Mid(strXl, i - 3, 1))
LastUser = Mid(strXl, i, lNameLen)
End Function
Testen:
Sub TestVBA()
'http://www.xcelfiles.com/IsFileOpenVBA.htm
'// Just change the file to test here
Const strFileToOpen As String = "...\Test.docx"
If IsFileOpen(strFileToOpen) Then
MsgBox strFileToOpen & " is already Open" & _
vbCrLf & "By " & LastUser(strFileToOpen), vbInformation, "File in Use"
Else
MsgBox strFileToOpen & " is not open", vbInformation
End If
End Sub
Mir wird aber kein Benutzername angezeigt!
Gängiger Weg, eine DLL in das Script einbinden als ActiveX und schon kommst Du an Username, Grafikkartenhersteller und kannst die Zwischenablage auslesen.
Ich glaube du hast beim falschen geantwortet? Zumindest wollte ich nichts mit einer Grafikkarte wissen :-)
Braucht man vielleicht Admin-Rechte auf das Netzlaufwerk? Der Code läuft ja ohne Fehler und zeigt nur den Namen nicht an. Habe über Deinen Link das Problem auch bei einer weiteren Person gefunden, aber die Antworten enthielten keine Lösung. :-(