Funkcja VBA i SQL

BU
  • Rejestracja:ponad 22 lata
  • Ostatnio:2 minuty
  • Postów:297
0

Witam społeczność,
Napisałem pewną funkcję w VBA. Oto jej kod:

Kopiuj
Function Wylicz(addressCell As String, cityCell As String, startDate As String, endDate As String)
Dim address As String
Dim city As String

address = Replace(addressCell, " ", "%")
city = Replace(cityCell, " ", "%")

Dim objRec As ADODB.Recordset
Dim objConn As ADODB.Connection
Dim cmdString As String

'Set objRec = CreateObject("ADODB.Recordset")
'Set objConn = CreateObject("ADODB.Connection")

objConn.ConnectionString = "Driver={SQL Server};Server=serwer;Database=baza;User ID=user;Password=haslo"
objConn.Open

cmdString = "DECLARE @table AS TGroups" + Chr(13)
cmdString = cmdString + "GO" + Chr(13)
cmdString = cmdString + "INSERT INTO @table (groupName) VALUES ('Grupa1')" + Chr(13)
cmdString = cmdString + "GO" + Chr(13)
cmdString = cmdString + "INSERT INTO @table (groupName) VALUES ('Grupa2')" + Chr(13)
cmdString = cmdString + "GO" + Chr(13)
cmdString = cmdString + "INSERT INTO @table (groupName) VALUES ('Grupa3')" + Chr(13)
cmdString = cmdString + "GO" + Chr(13)

Set objRec = objConn.Execute(cmdString)


cmdString = "EXEC dbo.SprzedazPoAdresieDostawy @groups = @table, @address = address, @city = city, @startDate = startDate, @endDate = endDate"

Set objRec = objConn.Execute(cmdString)

If objRec.EOF = True Then
    Wylicz = 0
Else
    Wylicz = objRec!ACTINDX
End If
objConn.Close
End Function

Niestety, ale funkcja nie chce działać. W przypadku wywołania:

Kopiuj
=Wylicz(C1;D1;"2024-04-01";"2024-04-30")

w komórce Excela pojawia się charakterystyczne #ARG!
Co jest nie tak?


Pozdrawiam
Buster
edytowany 1x, ostatnio: Buster
Ales
  • Rejestracja:około 6 lat
  • Ostatnio:17 dni
  • Postów:121
0

Dwa pierwsze parametry to stringi a podajesz typ range

BU
  • Rejestracja:ponad 22 lata
  • Ostatnio:2 minuty
  • Postów:297
0

Ale kiedy wstawiałem na sztywno stringi, było to samo.


Pozdrawiam
Buster
Ales
  • Rejestracja:około 6 lat
  • Ostatnio:17 dni
  • Postów:121
0

A debuger co mówi? Na której linijce wyrzuca wyjątek?
Spróbuj jeszcze oznaczyć funkcję jako publiczną

BU
  • Rejestracja:ponad 22 lata
  • Ostatnio:2 minuty
  • Postów:297
0

W tym rzecz, że nie wyrzuca żadnego wyjątku. Próbowałem wstawić MsgBox po pierwszym zapytaniu. Ale nawet nie pojawił się komunikat.


Pozdrawiam
Buster
Ales
  • Rejestracja:około 6 lat
  • Ostatnio:17 dni
  • Postów:121
0

Zmień function na sub. Usuń parametry i odpal tę metodę. Poczytaj jak obsługiwać debuger w vba

BU
  • Rejestracja:ponad 22 lata
  • Ostatnio:2 minuty
  • Postów:297
0

Coś nie idzie. Kompletnie nie mam pojęcia jak to zrobić. Pierwszy raz się mierzę z funkcją. Do tej pory robiłem takie rzeczy jako procedury wywoływane z przycisku. A teraz muszę zrobić to jako funkcja. Podpowiedzcie coś więcej.


Pozdrawiam
Buster
BU
  • Rejestracja:ponad 22 lata
  • Ostatnio:2 minuty
  • Postów:297
0

Po wielu próbach zmodyfikowałem funkcję:

Kopiuj
Public Function Wylicz(addressCell As String, cityCell As String, startDate As String, endDate As String)

Dim address As String
Dim city As String

address = Replace(addressCell, " ", "%")
city = Replace(cityCell, " ", "%")

Dim objRec As ADODB.Recordset
Dim objConn As ADODB.Connection
Dim objCmd As ADODB.Command
Dim ConnectionString As String
Dim cmdString As String

Set objRec = New ADODB.Recordset
Set objConn = New ADODB.Connection
Set objCmd = New ADODB.Command

ConnectionString = "Provider=SQLOLEDB;Data source=Serwer;Initial catalog=Baza;User ID=sa;Password=haslo"
objConn.Open ConnectionString

objCmd.ActiveConnection = objConn
objCmd.CommandType = adCmdText

cmdString = "DECLARE @table AS TGroups"

objCmd.CommandText = cmdString
objCmd.Execute , , adExecuteNoRecords
MsgBox ("Declare")

cmdString = "INSERT INTO @table (groupName) VALUES ('Grupa 1')"
objCmd.CommandText = cmdString
objCmd.Execute , , adExecuteNoRecords
MsgBox ("1 INSERT")

cmdString = "INSERT INTO @table (groupName) VALUES ('Grupa 2')"
objCmd.CommandText = cmdString
objCmd.Execute , , adExecuteNoRecords
MsgBox ("2 INSERT")

cmdString = "INSERT INTO @table (groupName) VALUES ('Grupa 3')"
objCmd.CommandText = cmdString
objCmd.Execute , , adExecuteNoRecords
MsgBox ("3 INSERT")

cmdString = "EXEC dbo.SprzedazPoAdresieDostawy @groups = @table, @address = address, @city = city, @startDate = startDate, @endDate = endDate"
MsgBox (cmdString)
Set objRec = objConn.Execute(cmdString)

If objRec.EOF = True Then
    Wylicz = 0
    'MsgBox (0)
Else
    Wylicz = objRec!ACTINDX
    'MsgBox (objRec!ACTINDX)
End If
objConn.Close
End Function

I teraz tak. Pierwsze zapytanie przechodzi, bo komunikat się pojawia. Ale następne już nie idą. Żaden z następnych komunikatów się nie pojawia. Kompletnie nie wiem co się dzieje. Najgorsze jest to, że nie ma żadnego błędu. Nigdzie się nie zatrzymuje. Wygląda to tak, jakby po pierwszym zapytaniu funkcja się zatrzymywała, zamykało się połączenie z bazą, albo nie wiem co jeszcze może się dziać.


Pozdrawiam
Buster
edytowany 1x, ostatnio: Buster
Ales
  • Rejestracja:około 6 lat
  • Ostatnio:17 dni
  • Postów:121
1

Zmień function na sub i debuguj. Postaw breakpoint I krokowo sprawdzaj każdą linie

BU
  • Rejestracja:ponad 22 lata
  • Ostatnio:2 minuty
  • Postów:297
0

Już chyba wiem o co chodzi. Wywołanie procedury składowanej z poziomu VBA musi być inaczej. Poza tym, z tego co czytałem, to ADODB w VBA nie obsługuje zmienny typu TABLE.

UPDATE
Jednak działa. Dodałem na początku SET NOCOUNT ON i ruszyło. Ale nie zwraca żadnego wyniku (objRec.RecordCount zwraca -1). Co prawda warunek wchodzi w wyświetlenie danych, ale pojawia się błąd, że brak indeksu czy coś w tym stylu.
Może ktoś by mi jednak coś zasugerował?


Pozdrawiam
Buster
edytowany 1x, ostatnio: Buster
BU
  • Rejestracja:ponad 22 lata
  • Ostatnio:2 minuty
  • Postów:297
0

I jest. Udało się. Wszystko działa. Dzięki za wsparcie i za pomoc. Pomogło dodanie na początku SET NOCOUNT ON i na końcu SET NOCOUNT OFF. W końcu sukces.


Pozdrawiam
Buster

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.