Plik do pobrania
Sub Raport(Target As Range, SQL As String, Optional Name) Dim sConn As String Dim sPath As String Dim sName As String Dim qt As QueryTable Dim wks As Excel.Worksheet If IsMissing(Name) Then ' sprawdź czy taki obiekt nie istnieje sName = "Lista" Else sName = CStr(Name) End If On Error Resume Next If ThisWorkbook.Names(sName).Name <> "" Then If Err.Number = 0 Then sName = sName & "_1" End If Err.Clear End If On Error GoTo ERR_Handler: ' ścieżka do pliku roboczego sPath = ThisWorkbook.Path & "\" & ThisWorkbook.Name ' Connection String sConn = "OLEDB;Provider=Microsoft.Jet.OLEDB.4.0;Password=;User ID=Admin;Data Source=" & sPath & ";" & _ "Mode=Share Deny Write;Extended Properties=""HDR=YES;"";" & _ "Jet OLEDB:Engine Type=35;Jet OLEDB:Database Locking Mode=0;" ' skoroszyt roboczy Set wks = Target.Parent ' sprawdź czy obiekt istnieje If wks.QueryTables.Count > 0 Then ' generuje błąd jak QT nie ma, działanie celowe Set qt = wks.QueryTables(sName) Else ' generuj błąd braku obiektu Err.Raise 9 End If With qt ' tworzymy obiekt QueryTable we wskazanej lokalizacji .CommandType = xlCmdSql ' informacja o tym że korzystamy z polecenia SQL .CommandText = SQL ' Komenda SQL, gdzie [Sheet1$] skoroszytem, po wstawieniu np. [lista] pobieramy dane z zakresu nazwanego .Name = sName ' nazwa obiektu Querytable .Refresh BackgroundQuery:=False 'pobieramy dane End With END_Handler: Exit Sub ERR_Handler: Select Case Err.Number Case 9 ' tworzenie obiektu Set qt = wks.QueryTables.Add(Connection:=sConn, Destination:=Target) Resume Next Case Else MsgBox Err.Description Resume END_Handler: End Select End Sub ' przykład wykorzystania Sub test() ' wyswietl elementy ze skoroszytu Sheet1, znak $ konieczny do tego żeby JET wiedział że to cały skoroszyt Raport Sheet3.Range("A1"), "select * from [Sheet1$]", "Wynik_2" 'policz oraz sumuj elementy z obszaru nazwanego lista Raport Sheet3.Range("D1"), "select count(*) as ILE, sum(R) as [S] from [lista]", "Wynik_3" End Sub
Ja to jestem zbyt cięki żeby być pewny że to co napiszę to 100% prawdy ale:
OdpowiedzUsuńSub test()
Dim Ark As Worksheet, sSqL As String, sciezka As String
sciezka = ThisWorkbook.FullName
sciezka = Left(sciezka, InStrRev(sciezka, ".", Len(sciezka)) - 1)
Set Ark = ThisWorkbook.Worksheets("Arkusz1")
MsgBox Ark.QueryTables.Count
'sSqL = "SELECT * " & Chr(13) & "" & Chr(10) & "FROM `" & sciezka & "`.Wynik_2" 'zdefiniowany zakres
sSqL = "SELECT * " & Chr(13) & "" & Chr(10) & "FROM `" & sciezka & "`.[Arkusz2$]"
Raport Ark.Range("A1"), sSqL ', "Wynik_2"
MsgBox Ark.QueryTables.Count
End Sub
czemu Ark.QueryTables.Count bo jeżeli np: podamy nazwę nie istniejącego Arkusza to zostanie utworzona kwerenda, byk i END_Handler .... (groźba utworzenia masy kwerend)
może więc w Case Else
MsgBox Err.Description
wks.QueryTables(wks.QueryTables.Count).Delete
Resume END_Handler:
kolejny urok QueryTables to tworzone nazwy (zdefiniowane zakresy). :D Sprawdź Ark.Names.Count i co sie na to składa
OdpowiedzUsuń- z tym nie wiem jak sobie poradzić
jakimś wyjściem jest usunięcie ostatnio dodanej nazwy (lub poprostu nazwy sName)
OdpowiedzUsuńEND_Handler:
'wks.Names(wks.Names.Count).Delete
wks.Names(sName).Delete
Exit Sub
T
A może by tak pobierać dane tekstowe do Excela za pomocą SQL, to może być interesujące dla czytających. Może dla utrudnienia dodam że dane mogą zawierać w każdym wierszu datę więc możemy filtrować import po dacie.
OdpowiedzUsuń