piątek, 10 kwietnia 2009

Jak sprawdzić czy istnieje arkusz w pliku XLS

Czasem taka prosta czynność może zaoszczędzić wiele zdenerwowania zwłaszcza przed importem danych z pliku Excel.

Poniżej przedstawię proste rozwiązanie tego problemu przy pomocy funkcji w VBA. jest ona na tyle przenośna że z powodzeniem może być również zastosowana do dowolnym innym miejscu.


Function sheetexist(fileName As String, sName As String) As Boolean
Dim myExcel As Object 'Excel.Application
Dim myWorkBook As Object 'Excel.Workbook
Dim CurrentSheet As Object 'Excel.Worksheet

sheetexist = False

If Dir(fileName) = "" Then
Exit Function
End If

Set myExcel = CreateObject("Excel.Application")
Set myWorkBook = myExcel.Workbooks.Open(fileName:=fileName)

For Each CurrentSheet In myWorkBook.Worksheets
If CurrentSheet.Name = sName Then
sheetexist = True
Exit For
End If
Next

myWorkBook.Close SaveChanges:=False
myExcel.Quit

Set myWorkBook = Nothing
Set myExcel = Nothing

End Function

Czy User jest w danej grupie

Dziś pokażę jak w miarę prosty sposób sprawdzić czy aktualnie zalogowany user jest członkiem konkretnej grupy. Jak wiadowmo User może być członkiem wielu grup jednocześnie co powoduje że musimy zadeklarować w czym chcemy sprawdzić.

pierwszym krokiem jest stworzenie obiektu który będzie odpytyany. Jest to kwerenda z zewnętrznym źródłem danych. Nazwijmy ją np. UserInGroup


PARAMETERS GroupName Text ( 255 );
SELECT DISTINCT Count(Accounts.FGroup) AS chk
FROM MSysAccounts AS Accounts INNER JOIN (MSysAccounts AS Accounts_1 INNER JOIN MSysGroups AS Groups ON Accounts_1.SID = Groups.GroupSID) ON Accounts.SID = Groups.UserSID IN 'C:\Users\Orzemek\AppData\Roaming\Microsoft\Access\System.mdw'
WHERE (((Accounts_1.Name)=[GroupName]) AND ((Accounts.Name)=CurrentUser()) AND ((Accounts.FGroup)=0) AND ((Accounts_1.FGroup)<>0));


kolejnym elementem jest funkcja sprawdzająca


Function currentgrups(GroupName As String) As Boolean

currentgrups = CBool(CurrentProject.Connection.Execute("execute UserInGroup @GroupName ='" & GroupName & "'").Fields(0).Value)

End Function

Jest to taki typowy skrótowiec :) przedstawię go w prostszej postaci z komentarzem

Function currentgrups(GroupName As String) As Boolean

Dim aRs As ADODB.Recordset
Dim sSql As String
' tu wstawiamy kod SQL który chcemy wykonać
sSql = "execute UserInGroup @GroupName ='" & GroupName & "'"
' uruchamiamy kod SQL za pomocą aktywnego połączenia bazy danych
Set aRs = CurrentProject.Connection.Execute(sSql)
'pobieramy wartość pierwszej kolumny (uwaga zaczynamy liczyć od 0)
'i konwertujemy wynik do wartości prawda / fałsz
currentgrups = CBool(aRs.Fields(0).Value)

End Function


w szczególnym przypadku możemy zrezygnować z tworzeia dodatkowego obiektu na rzecz dynamicznego SQL-a. Funkcja wtedy wyglądała by następująco:

Function currentgrups(GroupName As String) As Boolean

Dim aRs As ADODB.Recordset
Dim sSql As String

Const spacjs As String = " "
' deklaracja ze ścieżką do zdalnego pliku z hasłami
Const plik_z_pass As String = "d:\System.mdw"
' tu wstawiamy kod SQL który chcemy wykonać
sSql = ""
sSql = sSql & "SELECT DISTINCT Count(Accounts.FGroup) AS chk" & spacjs
sSql = sSql & "FROM MSysAccounts AS Accounts INNER JOIN (MSysAccounts AS Accounts_1 INNER JOIN MSysGroups AS Groups ON Accounts_1.SID = Groups.GroupSID) ON Accounts.SID = Groups.UserSID" & spacjs
sSql = sSql & "IN '" & plik_z_pass & "'" & spacjs
sSql = sSql & "WHERE (((Accounts_1.Name)='" & GroupName & "') AND ((Accounts.Name)=CurrentUser()) AND ((Accounts.FGroup)=0) AND ((Accounts_1.FGroup)<>0));"

' uruchamiamy kod SQL za pomocą aktywnego połączenia bazy danych
Set aRs = CurrentProject.Connection.Execute(sSql)
'pobieramy wartość pierwszej kolumny (uwaga zaczynamy liczyć od 0)
'i konwertujemy wynik do wartości prawda / fałsz
currentgrups = CBool(aRs.Fields(0).Value)

End Function