Got a stupid problem, it seams simple but I just don't get it.
Got a very simple vba code for an excel sheet:
Private Sub GET_MDW_DATA()
On Error GoTo ErrorHandler
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
Dim cmdSQLData As ADODB.Command
Set cmdSQLData = New ADODB.Command
Dim cnstr As String
Dim usr
Set usr = Nothing
usr = Sheet1.Cells(1, 4).Value
Dim pwd
Set pwd = Nothing
pwd = Sheet1.Cells(2, 4).Value
Dim odbcname
Set odbcname = Nothing
odbcname = Sheet1.Cells(1, 8).Value
Dim Category As String
Category = Sheet1.Cells(1, 6).Value
Dim Store As String
Store = Sheet1.Cells(2, 6).Value
cnstr = "Data Source=" & odbcname & "; Database=belccp_msi_d; Persist Security Info=True; User ID=" & usr & "; Password=" & pwd & "; Session Mode=ANSI;"
cn.Open cnstr
Set cmdSQLData.ActiveConnection = cn
Sheet1.Range("A6 : H1000000").Clear
Query = "SELECT SOMETHING FROM SOME DATABASE"
cmdSQLData.CommandText = Query
cmdSQLData.CommandType = adCmdText
cmdSQLData.CommandTimeout = 0
Set rs = cmdSQLData.Execute()
rs.MoveFirst
x = 6
Do While (rs.BOF = False or rs.EOF = False)
p = rs.GetRows(-1)
Sheet1.Range("A" & x).Value = p(0, 8)
Sheet1.Range("B" & x).Value = p(1, 8)
Sheet1.Range("C" & x).Value = p(2, 8)
Sheet1.Range("D" & x).Value = p(3, 8)
Sheet1.Range("E" & x).Value = p(4, 8)
Sheet1.Range("F" & x).Value = p(5, 8)
Sheet1.Range("G" & x).Value = p(6, 8)
Sheet1.Range("H" & x).Value = p(7, 8)
x = x + 1
Loop
cn.Close
Set cn = Nothing
Set rs = Nothing
Set cmdSQLData = Nothing
If I "print" my select, copy it and execute it in an query, it returns 30 rows from my database, but when I execute it from my excel "code" it only returns 1 row, only one line from the 30 lines.
I have checked it and just before x=x+1 the rs.EOF is True. That means either that my record set has only one value (if so why? because my select returns 30 rows) or that I don't parse it correctly. Any hints?
Many thanks in advance,
A strange thing that I noticed in your code is that you use the GetRows function in a loop.
GetRows loads the recordset into an array.
Either you loop through the array returned by GetRows, or you loop through the recordset. There is no reason why you would do both at the same time.
In case you loop through the recordset, you would have something like:
x = 6 'As you prefer
rs.MoveFirst
Do Until rs.EOF
Sheet1.Range("A" & x).Value = rs![field_name_1]
Sheet1.Range("B" & x).Value = rs![field_name_2]
Sheet1.Range("C" & x).Value = rs![field_name_3]
Sheet1.Range("D" & x).Value = rs![field_name_4]
Sheet1.Range("E" & x).Value = rs![field_name_5]
Sheet1.Range("F" & x).Value = rs![field_name_6]
Sheet1.Range("G" & x).Value = rs![field_name_7]
Sheet1.Range("H" & x).Value = rs![field_name_8]
rs.MoveNext
Loop
To check how many records there are in your recordset, use:
rs.MoveLast
iRecordCount = rs.RecordCount
Related
I have a program, that works, I just feel that it is running slower than it should and I feel that it is a bit more unstable than it should be. I am looking for tips on writing "better" code and making my program more stable.
I am looking to better this part of my code for now:
Private Sub Worksheet_Activate()
Application.ScreenUpdating = False
'Removes shapes already there that will be updated by the getWeather function
For Each delShape In Shapes
If delShape.Type = msoAutoShape Then delShape.Delete
Next delShape
'Calls a function to get weather data from a web service
Call getWeather("", "Area1")
Call getWeather("", "Area2")
Call getWeather("", "Area3")
'Starting to implement the first connection to a SQL Access database.
Dim cn As Object
Dim rs As Object
'Set cn and sqlConnect as ADODB-objects. Set rs as recordset
Set cn = CreateObject("ADODB.Connection")
Set sqlConnect = New ADODB.Connection
Set rs = CreateObject("ADODB.RecordSet")
'Set sqlConnect as connection string
sqlConnect.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\databases\database.accdb;Persist Security Info=False;"
'Open connection string via connection object
cn.Open sqlConnect
'Set rs.Activeconnection to cn
rs.ActiveConnection = cn
'Get a username from the application to be used further down
Brukernavn = Application.userName
'This part of the code re-arranges the date format from american to european
StartDate = Date
EndDate = Date - 7
midStartDate = Split(StartDate, ".")
midEndDate = Split(EndDate, ".")
StartDate2 = "" & midStartDate(1) & "/" & midStartDate(0) & "/" & midStartDate(2) & ""
EndDate2 = "" & midEndDate(1) & "/" & midEndDate(0) & "/" & midEndDate(2) & ""
'SQL statement to get data from the access database
rs.Open "SELECT [RefNr], [Registrert Av],[Nettstasjon], [Meldt Dato] , [Bestilling], [Sekundærstasjon], [Avgang], [Hovedkomponent], [HovedÅrsak], [Status Bestilling] FROM [tblDatabase]" & _
"WHERE [Registrert Av] = '" & Brukernavn & "' AND [Loggtype] <> 'Beskjed' AND [Meldt Dato] BETWEEN #" & StartDate2 & "# AND # " & EndDate2 & "#" & _
"ORDER BY [Meldt Dato] DESC;", _
cn, adOpenStatic
'Start to insert data from access database into a list
Dim i As Integer
Dim u As Integer
If Not rs.EOF Then
rs.MoveFirst
End If
i = 0
With lst_SisteFeil
.Clear
Do
If Not rs.EOF Then
.AddItem
If Not IsNull(rs!refnr) Then
.List(i, 0) = rs![refnr]
End If
If IsDate(rs![Meldt Dato]) Then
.List(i, 1) = Format(rs![Meldt Dato], "dd/mm/yy")
End If
.List(i, 4) = rs![nettstasjon]
If Not IsNull(rs![Sekundærstasjon]) Then
.List(i, 2) = rs![Sekundærstasjon]
End If
If Not IsNull(rs![Avgang]) Then
.List(i, 3) = rs![Avgang]
End If
If Not IsNull(rs![Hovedkomponent]) Then
.List(i, 5) = rs![Hovedkomponent]
End If
If Not IsNull(rs![HovedÅrsak]) Then
.List(i, 6) = rs![HovedÅrsak]
End If
If Not IsNull(rs![Status Bestilling]) Then
.List(i, 7) = rs![Status Bestilling]
End If
If Not IsNull(rs![bestilling]) Then
.List(i, 8) = rs![bestilling]
End If
i = i + 1
rs.MoveNext
Else
GoTo endOfFile
End If
Loop Until rs.EOF
End With
endOfFile:
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
'Starts to connect to SQL access database again to get different set of data. This must be possible to make more efficient?
Dim cn2 As Object
Dim rs2 As Object
'Set cn and sqlConnect as ADODB-objects. Set rs as recordset
Set cn2 = CreateObject("ADODB.Connection")
Set sqlConnect2 = New ADODB.Connection
Set rs2 = CreateObject("ADODB.RecordSet")
'Set sqlConnect as connection string
sqlConnect2.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\databases\database.accdb;Persist Security Info=False;"
'Open connection string via connection object
cn2.Open sqlConnect
'Set rs.Activeconnection to cn
rs2.ActiveConnection = cn2
'Second SQL statement
rs2.Open "SELECT [RefNr], [Registrert Av],[Nettstasjon], [Meldt Dato] , [Bestilling], [Sekundærstasjon], [Avgang], [Hovedkomponent], [HovedÅrsak], [Status Bestilling] FROM [tblDatabase]" & _
"WHERE [Registrert Av] <> '" & Brukernavn & "' AND [Meldt Dato] BETWEEN #" & StartDate2 & "# AND # " & EndDate2 & "#" & _
"ORDER BY [Meldt Dato] DESC;", _
cn2, adOpenStatic
'Inserting into second list
If Not rs2.EOF Then
rs2.MoveFirst
End If
u = 0
With lst_AlleFeil
.Clear
Do
If Not rs2.EOF Then
.AddItem
If Not IsNull(rs2!refnr) Then
.List(u, 0) = rs2![refnr]
End If
If IsDate(rs2![Meldt Dato]) Then
.List(u, 1) = Format(rs2![Meldt Dato], "dd/mm/yy")
End If
.List(u, 4) = rs2![nettstasjon]
If Not IsNull(rs2![Sekundærstasjon]) Then
.List(u, 2) = rs2![Sekundærstasjon]
End If
If Not IsNull(rs2![Avgang]) Then
.List(u, 3) = rs2![Avgang]
End If
If Not IsNull(rs2![Hovedkomponent]) Then
.List(u, 5) = rs2![Hovedkomponent]
End If
If Not IsNull(rs2![HovedÅrsak]) Then
.List(u, 6) = rs2![HovedÅrsak]
End If
If Not IsNull(rs2![Status Bestilling]) Then
.List(u, 7) = rs2![Status Bestilling]
End If
If Not IsNull(rs2![bestilling]) Then
.List(u, 8) = rs2![bestilling]
End If
u = u + 1
rs2.MoveNext
Else
GoTo endOfFile2
End If
Loop Until rs2.EOF
End With
endOfFile2:
rs2.Close
cn2.Close
Set rs2 = Nothing
Set cn2 = Nothing
'Starting to connect to the database for the third time
Dim cn3 As Object
Dim rs3 As Object
'Set cn and sqlConnect as ADODB-objects. Set rs as recordset
Set cn3 = CreateObject("ADODB.Connection")
Set sqlConnect3 = New ADODB.Connection
Set rs3 = CreateObject("ADODB.RecordSet")
'Set sqlConnect as connection string
sqlConnect3.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\databases\database.accdb;Persist Security Info=False;"
'Open connection string via connection object
cn3.Open sqlConnect
'Set rs.Activeconnection to cn
rs3.ActiveConnection = cn3
'third sql statement
rs3.Open "SELECT [RefNr], [Registrert Av],[Nettstasjon], [Meldt Dato], [Sekundærstasjon], [Avgang], [Beskrivelse], [Til Dato] FROM [tblDatabase]" & _
"WHERE [Loggtype] = 'Beskjed' AND [Meldt Dato] >= DateAdd('d',-30,Date())" & _
"ORDER BY [Meldt Dato] DESC;", _
cn3, adOpenStatic
'Inserting data in to third list
If Not rs3.EOF Then
rs3.MoveFirst
End If
j = 0
With lst_beskjeder
.Clear
Do
If Not rs3.EOF Then
.AddItem
If Not IsNull(rs3!refnr) Then
.List(j, 0) = rs3![refnr]
End If
If IsDate(rs3![Meldt Dato]) Then
.List(j, 1) = Format(rs3![Meldt Dato], "dd/mm/yy")
End If
.List(j, 4) = rs3![nettstasjon]
If Not IsNull(rs3![Sekundærstasjon]) Then
.List(j, 2) = rs3![Sekundærstasjon]
End If
If Not IsNull(rs3![Avgang]) Then
.List(j, 3) = rs3![Avgang]
End If
If Not IsNull(rs3![beskrivelse]) Then
.List(j, 5) = rs3![beskrivelse]
End If
j = j + 1
rs3.MoveNext
Else
GoTo endOfFile3
End If
Loop Until rs3.EOF
End With
endOfFile3:
rs3.Close
cn3.Close
Set rs3 = Nothing
Set cn3 = Nothing
End Sub
Here is the function I have used to get weather data.
Public Sub getWeather(APIurl As String, sted As String)
Dim i As Integer
i = 0
Dim omraade As String
omraade = ""
omraade = sted
If sted = "Area1" Then
i = 4
ElseIf sted = "Area2" Then
i = 6
ElseIf sted = "Area3" Then
i = 8
End If
Dim WS As Worksheet: Set WS = ActiveSheet
Dim delShape As Shape
Dim city As String
Dim Req As New XMLHTTP
Req.Open "GET", "" & APIurl & "", False
Req.Send
Dim Resp As New DOMDocument
Resp.LoadXML Req.responseText
Dim Weather As IXMLDOMNode
Dim wShape As Shape
Dim thisCell As Range
For Each Weather In Resp.getElementsByTagName("current_condition")
Set thisCell = WS.Range(Cells(2, i), Cells(2, i))
Set wShape = WS.Shapes.AddShape(msoShapeRectangle, thisCell.Left, thisCell.Top, thisCell.Width, thisCell.Height)
wShape.Fill.UserPicture Weather.ChildNodes(4).Text 'img
Cells(3, i).Value = "" & Weather.ChildNodes(7).Text * 0.28 & " m/s" 'windspeedkmph
Cells(4, i).Value = Weather.ChildNodes(9).Text 'Direction
Cells(5, i).Value = Weather.ChildNodes(1).Text & " C" 'observation time
Next Weather
End Sub
Feel free to point out any poor coding and tips on how to improve it. I am currently using the Worksheet Activate sub to activate changes in the tables and get new data, but I suspect that is not the best solution. I am just not sure how else to do it seeing as I want it to be as "automatic" as possible, and use as few buttons to refresh as I can.
Thank you for all the help.
-Thomas
Some tips, but none will affect performance, only help make your code more succinct.
1.
rs.Open "SELECT ..."
If Not rs.EOF Then
rs.MoveFirst
End If
.MoveFirst is unnecessary. After opening a recordset, you are always on the first record, if there are records.
When building complex SQL in VBA, have a look at How to debug dynamic SQL in VBA.
2.
Don't do a Do ... Until loop for recordsets:
Do
If Not rs.EOF Then
' do stuff for each record
' ...
rs.MoveNext
Else
GoTo endOfFile
End If
Loop Until rs.EOF
endOfFile:
rs.Close
Instead use Do While Not rs.EOF :
Do While Not rs.EOF
' do stuff for each record
' ...
rs.MoveNext
Loop
rs.Close
For an empty rs, the loop will not be entered. You don't need the If/Else and the Goto.
I have two workbooks, call them Book1 and Book2. Book1 is open, and I am trying to get data from Book2, which is closed, into Book1. Book1 contains a column listing a corresponding element in Book2. For example, Book1 has a column of numbers that correspond to another list of numbers in Book2. I am trying to use VBA to get data from a row in Book2 with the matching number to the one in Book1.
Right now, I have the following MWE that generates an Error 91 (Object Not Set) when I try to execute the code:
Dim path As String, book As String, sheet As String
Dim targetRng As Range, sourceRng As Range
path = Left(Cells(2, 1).Value, InStrRev(Cells(2, 1).Value, "\"))
book = Dir(Cells(2, 1).Value)
sheet = Cells(2, 2).Value
Set targetRng = Range("A1").CurrentRegion
Set targetRng = targetRng.Offset(1, 0).Resize(targetRng.Rows.Count - 1) 'Ignore header row
For i = 1 To targetRng.Rows.Count
Set sourceRng = "'" & path & "[" & book & "]" & sheet & "'!" & Range("A:A").Find(targetRng.Cells(i, 1).Value) 'Error is here
targetRng.Cells(i, 2).Value = ExecuteExcel4Macro("'" & path & "[" & book & "]" & sheet & "'!" & Cells(sourceRng.Row, 2).Address)
'
'Do some other stuff
'
Next i
I was reluctant to provide an answer using the ADO because it is a broad topic. But I will provide you two examples of how you con query a Excel files using the ADO.
On the left we have the source file that we will be querying [Employees.xlsx]. On the right we workbook that we are updating [Sample.xlsm]. In my examples we are using [Sheet1] of booth workbooks. Note that the ADO will use column headers as field names (id,first_name,last_name...etc.).
In Example1 we query [Employees.xlsx] loading all the records from [Employees.xlsx]![Sheet1] into the recordset EmployeeData. Next we iterate over the id column of [Sample.xlsm]![Sheet1] and setting the filter of the recordset EmployeeData.Filter = "id=" & Cells(x, 1). Then copy the values of the records fields to the appropriate cell .Cells(x, 2) = EmployeeData.Fields("first_name")
Sub Example1()
Dim lastRow As Long, x As Long
Const adOpenKeyset = 1
Const adLockOptimistic = 3
Dim conn
Dim EmployeeData
Set conn = CreateObject("ADODB.Connection")
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=I:\stackoverflow\Employees.xlsx;Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
conn.Open
On Error GoTo CloseConnection
Set EmployeeData = CreateObject("ADODB.Recordset")
With EmployeeData
.ActiveConnection = conn
.CursorType = adOpenKeyset
.LockType = adLockOptimistic
.Source = "Select * FROM [Sheet1$]"
.Open
On Error GoTo CloseRecordset
End With
With Worksheets("Sheet1")
lastRow = .Range("A" & Rows.Count).End(xlUp).Row
For x = 2 To lastRow
EmployeeData.Filter = "id=" & Cells(x, 1)
If Not (EmployeeData.BOF And EmployeeData.EOF) Then
.Cells(x, 2) = EmployeeData.Fields("first_name")
.Cells(x, 3) = EmployeeData.Fields("last_name")
.Cells(x, 4) = EmployeeData.Fields("email")
.Cells(x, 5) = EmployeeData.Fields("gender")
.Cells(x, 6) = EmployeeData.Fields("ip_address")
End If
Next
End With
CloseRecordset:
EmployeeData.Close
Set EmployeeData = Nothing
CloseConnection:
conn.Close
Set conn = Nothing
End Sub
In Example2 we Left Join [Sample.xlsm]![Sheet1] with [Employees.xlsx]![Sheet1]. In this way, we use CopyFromRecordset to update the data for us.
Sheet1.Range("A2").CopyFromRecordset EmployeeData.
Sub Example2()
Dim lastRow As Long, x As Long
Const adOpenKeyset = 1
Const adLockOptimistic = 3
Dim conn
Dim EmployeeData
Set conn = CreateObject("ADODB.Connection")
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
conn.Open
On Error GoTo CloseConnection
Set EmployeeData = CreateObject("ADODB.Recordset")
With EmployeeData
.ActiveConnection = conn
.CursorType = adOpenKeyset
.LockType = adLockOptimistic
.Source = "SELECT table1.id, table2.[first_name], table2.[last_name], table2.[email], table2.[gender], table2.[ip_address] FROM ( [Sheet1$] table1 LEFT JOIN `I:\stackoverflow\Employees.xlsx`.`Sheet1$` table2 ON table2.[id]=table1.[id] )"
.Open
On Error GoTo CloseRecordset
End With
Sheet1.Range("A2").CopyFromRecordset EmployeeData
CloseRecordset:
EmployeeData.Close
Set EmployeeData = Nothing
CloseConnection:
conn.Close
Set conn = Nothing
End Sub
Note: CopyFromRecordset will replace all the data in the effected columns. For this reason recommend using Example 1 until you become comfortable writing queries.
Okay, I will paste in the code below. I'm trying to loop through the table in sql server 2008 but when excel opens up in only shows me the data for the first row in the table. How do I extend the loop to show me all the records in the table. The record count is 13, but i see only data ffor the first row (firstname, lastname)
Dim rs As New ADODB.Recordset
Dim strSQL As String
Dim X As Integer
Dim y As Integer
Dim strReportFileName As String
Dim strTmpMsg As String
Dim intResponse As Integer
Dim xlRow As Integer
Dim xlApp As Excel.Application
Dim xlBook As Excel.Workbook
Dim xlSheet As Excel.Worksheet
Set xlApp = New Excel.Application
Set xlBook = xlApp.Workbooks.Add
Set xlSheet = xlBook.Worksheets.Add
xlSheet.Name = "Test Extract"
With xlSheet.PageSetup
.Orientation = xlLandscape
End With
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
strSQL = "SELECT FirstName, LastName from dbo.tblTest_clients"
rs.Open strSQL, g_cnDatabase
Debug.Print strSQL
MsgBox rs.RecordCount
rs.MoveFirst
For y = 0 To rs.Fields.Count - 1
Select Case y
Case 0
With xlSheet.Cells(xlRow, y + 1)
If Not IsNull(rs("FirstName").Value) Then
.Value = rs("FirstName")
End If
End With
Case 1
With xlSheet.Cells(xlRow, y + 1)
If Not IsNull(rs("LastName").Value) Then
.Value = rs("LastName")
End If
End With
Case Else
'do nothing
End Select
Next y
If xlApp.Version = "10.0" Then
strReportFileName = g_strReportWriteDir & "\ClientInfo" & Format(Now, "YYYYMMDDHHNNSS") & ".xls "
xlBook.SaveAs strReportFileName
Else
strReportFileName = g_strReportWriteDir & "\ClientInfo" & Format(Now, "YYYYMMDDHHNNSS") & ".xls"
xlBook.SaveAs strReportFileName, 56
End If
xlBook.Close
Set xlSheet = Nothing
Set xlBook = Nothing
Set xlApp = Nothing
'xlApp.Quit
strTmpMsg = "Client Info Extract File: " & strReportFileName & " was created successfully."
intResponse = MsgBox(strTmpMsg & vbCrLf & vbCrLf & "Do you wish to View?" & vbCrLf & vbCrLf & "Viewing the Extract opens another program windo -please be sure to CLOSE it once you are done reviewing the extract.", vbYesNo, "Client Extract View Confirmation.....")
If intResponse = vbYes Then
If ShellEx(strReportFileName, essSW_SHOWMAXIMIZED, , , "Open", frmReports.hWnd) Then
End If
End If
rs.MoveFirst
With xlSheet.Cells(xlRow)
.Cells(1).Value = "First Name"
.Cells(2).Value = "Last Name"
End With
xlRow = xlRow + 1
Do While Not rs.EOF
With xlSheet.Cells(xlRow)
If Not IsNull(rs("FirstName").Value) Then .Cells(1).Value = rs("FirstName")
If Not IsNull(rs("LastName").Value) Then .Cells(2).Value = rs("LastName")
End With
rs.movenext
xlRow = xlRow + 1
Loop
You never set xlRow to any value or iterate over it, so the code is going to just keep writing to that row - hence, why you only see the last value in your.
You can do what you want with much cleaner code.
See Below
rs.MoveFirst
xlRow = 1
Do Until rs.EOF
'puts first name in column A
If Not IsNull(rs("FirstName")) Then xlSheet.Cells(xlRow, 1).Value = rs("FirstName")
'puts last name in column B
If Not IsNull(rs("LastName")) Then xlSheet.Cells(xlRow, 2).Value = rs("LastName")
rs.MoveNext
xlRow = xlRow + 1
Loop
I've some code in Excel that updates an Access table based on if RTP_ID equals IngID, the following matches and works if they are numeric in RTP_ID:
sSQL = "SELECT * FROM Tbl_Primary WHERE RTP_ID = " & lngID
However I would like it where RTP_ID could be a string.
I've tried:
sSQL = "SELECT * FROM Tbl_Primary WHERE RTP_ID = '" & lngID & "'"
but that still doesn't work, any ideas?
So if RTP_ID was 1 it would work, but if it was 1A it wouldn't.
Edit- here is the code I currently have:
Application.ScreenUpdating = False
Dim cnn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim fld As ADODB.Field
Dim MyConn
Dim lngRow As Long
Dim lngID, LR, Upd
Dim strID As String
Dim j As Long
Dim sSQL As String
LR = Range("B" & Rows.Count).End(xlUp).Row
Upd = LR - 1
lngRow = 2
Do While lngRow <= LR
strID = Cells(lngRow, 2).Value
sSQL = "SELECT * FROM Tbl_Primary WHERE RTP_ID2 = " & strID
Set cnn = New ADODB.Connection
MyConn = "Provider = Microsoft.ACE.OLEDB.12.0;" & _
"Data Source =\Work\Sites\HLAA\NEW\test\HLAA 2015 NEW.mdb"
With cnn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.Open MyConn
End With
Set rst = New ADODB.Recordset
rst.CursorLocation = adUseServer
rst.Open sSQL, ActiveConnection:=cnn, _
CursorType:=adOpenKeyset, LockType:=adLockOptimistic
.
With rst
.Fields("MonitorCapacity") = Cells(lngRow, 74).Value
rst.Update
End With
rst.Close
cnn.Close
Set rst = Nothing
Set cnn = Nothing
lngRow = lngRow + 1
Loop
MsgBox "You just updated " & Upd & " records"
I'd rewrite the code as below:
Dim cnn As Object
Dim lngRow As Long
Dim lngID As Long, LR As Long, Upd As Long
Dim strID As String
LR = ThisWorkbook.Worksheets("Sheet2").Range("B" & Rows.Count).End(xlUp).Row
Upd = LR - 1
lngRow = 2
Set cnn = CreateObject("ADODB.Connection")
cnn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=\Work\Sites\HLAA\NEW\test\HLAA 2015 NEW.mdb;" & _
"Persist Security Info=False;"
Do While lngRow <= LR
strID = ThisWorkbook.Worksheets("Sheet2").Cells(lngRow, 2).Value
cnn.Execute "UPDATE Tbl_Primary SET MonitorCapacity = '" & _
ThisWorkbook.Worksheets("Sheet2").Cells(lngRow, 74).Value2 & _
"' WHERE RTP_ID2 = '" & strID & "'"
lngRow = lngRow + 1
Loop
MsgBox "You just updated " & Upd & " records"
You may need to change the Worksheet name - when you just put Range("B" & Rows.Count) it will use whichever sheet is active at the time, so need to state the worksheet.
I am trying to develop a vbs to import data from excel to sql server.
Byte values are getting imported but in varchar field of DB, string values from Excel are not getting imported (the field is empty). below is code
Option Explicit
Const adOpenStatic = 3
Const adLockOptimistic = 3
dim strSqlInsertString,objConnection2,objRecordSet2
dim objExcel,objWorkBook,strRow
Set objConnection2 = CreateObject("ADODB.Connection")
Set objRecordSet2 = CreateObject("ADODB.Recordset")
objConnection2.Open "Provider=SQLOLEDB.1;Persist Security Info=False;User ID=appapollo;Password=dna;Initial Catalog=6057;Data Source=lxi282"
Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.Workbooks.Open _
("D:\Cardiopacs\Automation\Forward\test.xls")
strRow = 2
dim AEName,AEDescription,AEIPAddress,AEPort,ModifiedDate,QRSSApplicationEntityID,MobileAE,NotificationXML,PreFetch,PreFetchSuffix
strSqlInsertString = "INSERT INTO SSDICOMApplicationEntities (AEName,AEDescription,AEIPAddress,AEPort,ModifiedDate,QRSSApplicationEntityID,MobileAE," & _
"NotificationXML,PreFetch,PreFetchSuffix) " & _
"VALUES('" &AEName& "','" &AEDescription& "','" &AEIPAddress& "','" &AEPort& "','" &ModifiedDate& "','" &QRSSApplicationEntityID& "','" &MobileAE& "'," & _
"'" &NotificationXML& "','" &PreFetch& "','" &PreFetchSuffix& "')"
Do Until objExcel.Cells(strRow,1).Value = ""
'SSDIOMApplicationEntityID = objExcel.Cells(intRow, 1).Value
AEName = objExcel.Cells(strRow, 1).Value
AEDescription = objExcel.Cells(strRow, 2).Value
AEIPAddress = objExcel.Cells(strRow, 3).Value
AEPort = objExcel.Cells(strRow, 4).Value
ModifiedDate = objExcel.Cells(strRow, 5).Value
QRSSApplicationEntityID = objExcel.Cells(strRow, 6).Value
MobileAE = objExcel.Cells(strRow, 7).Value
NotificationXML = objExcel.Cells(strRow, 8).Value
PreFetch = objExcel.Cells(strRow, 9).Value
PreFetchSuffix = objExcel.Cells(strRow, 10).Value
strRow = strRow + 1
set objRecordSet2=objConnection2.execute(strSQLInsertString)
loop
objconnection2.close
set objConnection2 = Nothing
objExcel.Quit
The problem is that what your code does is
generate sql command with empty values
do until end
retrieve values from excel
execute sql command with empty values
loop
And what it should do is
do until end
retrieve values from excel
generate the new sql command from the retrieved values
execute the new generated sql command
loop