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ń