How to export spreadsheet data into SQLServer? - vba

I am new to Vba, hope someone will solve my problem. I am trying to update data present in my spreadsheet. Actually i have 20,000 records, each record has around 74 columns. So updating them record by record by using ADO taking so much of time. Is there any alternative approach to update those records in single shot. Any help would be appreciated greatly.
Currently my code is.
Sub InitialExport()
On Error GoTo ErrHandler
Dim con As New ADODB.Connection
Dim Query As String
Dim EffectedRecs As Long
Dim i As Integer
ServerName = "192.178.78.36"
'Setting ConnectionString
con.ConnectionString = "Provider=SQLOLEDB; " & _
"Data Source=" & ServerName & "; " & _
"Initial Catalog=AppEmp;" & _
"User ID=sa; Password=admin08; "
'Setting provider Name
con.Provider = "Microsoft.JET.OLEDB.12.0"
'Opening connection
con.Open
With ThisWorkbook.Sheets("Export")
For i = 3 To ThisWorkbook.Sheets("Export").Range("B65536").End(xlUp).Row
'---------------------->
EmpId = .Range("B" & i).Value 'Emp Code-varchar
C = .Range("C" & i).Value 'Emp Name-varchar
D = .Range("D" & i).Value
E = .Range("E" & i).Value
F = .Range("F" & i).Value
G = .Range("G" & i).Value
H = .Range("H" & i).Value
II = .Range("I" & i).Value
JJ = .Range("J" & i).Value
k = .Range("K" & i).Value
l = .Range("L" & i).Value
M = .Range("M" & i).Value
N = CheckNull(.Range("N" & i).Value)
O = CheckNull(.Range("O" & i).Value)
P = CheckNull(.Range("P" & i).Value)
Q = CheckNull(.Range("Q" & i).Value)
R = CheckNull(.Range("R" & i).Value)
S = .Range("S" & i).Value
T = .Range("T" & i).Value
U = .Range("U" & i).Value
v = .Range("V" & i).Value
W = .Range("W" & i).Value
X = CheckNull(.Range("X" & i).Value)
Y = .Range("Y" & i).Value
Z = .Range("Z" & i).Value
AA = CheckNull(.Range("AA" & i).Value)
AB = .Range("AB" & i).Value
AC = CheckNull(.Range("AC" & i).Value)
AD = CheckNull(.Range("AD" & i).Value)
AE = CheckNull(.Range("AE" & i).Value)
AF = CheckNull(.Range("AF" & i).Value)
AG = .Range("AG" & i).Value
AH = CheckNull(.Range("AH" & i).Value)
AI = CheckNull(.Range("AI" & i).Value)
AJ = CheckNull(.Range("AJ" & i).Value)
AK = CheckNull(.Range("AK" & i).Value)
AL = CheckNull(.Range("AL" & i).Value)
AM = CheckNull(.Range("AM" & i).Value)
AN = CheckNull(.Range("AN" & i).Value)
AO = CheckNull(.Range("AO" & i).Value)
AP = CheckNull(.Range("AP" & i).Value)
AQ = CheckNull(.Range("AQ" & i).Value)
AR = CheckNull(.Range("AR" & i).Value)
aAS = CheckNull(.Range("AS" & i).Value)
AT = .Range("AT" & i).Value
AU = CheckNull(.Range("AU" & i).Value)
AV = CheckNull(.Range("AV" & i).Value)
AW = CheckNull(.Range("AW" & i).Value)
AX = CheckNull(.Range("AX" & i).Value)
AY = CheckNull(.Range("AY" & i).Value)
AZ = CheckNull(.Range("AZ" & i).Value)
BA = CheckNull(.Range("BA" & i).Value)
BB = CheckNull(.Range("BB" & i).Value)
BC = CheckNull(.Range("BC" & i).Value)
BD = CheckNull(.Range("BD" & i).Value)
BE = .Range("BE" & i).Value
BF = .Range("BF" & i).Value
BG = CheckNull(.Range("BG" & i).Value)
BH = .Range("BH" & i).Value
BI = .Range("BI" & i).Value
BJ = CheckNull(.Range("BJ" & i).Value)
BK = CheckNull(.Range("BK" & i).Value)
BL = CheckNull(.Range("BL" & i).Value)
BM = .Range("BM" & i).Value
BN = .Range("BN" & i).Value
Query = "Exec HRApp_P_AddEmpData '" & EmpId & "','" & C & "','" & D & "','" & E & "','" & F & "','" & G & "','" & H & "','" & II & "','" & JJ & "','" & k & "','" & l & "','" & M & "'," & N & "," & O & "," & P & "," & Q & "," & R & ",'" & S & "','" & T & "','" & U & "','" & v & "','" & W & "'," & X & ",'" & Y & "','" & Z & "'," & AA & ",'" & AB & "'," & AC & "," & AD & "," & AE & "," & AF & ",'" & AG & "'," & AH & "," & AI & "," & AJ & "," & AK & ",'" & AL & "'," & AM & "," & AN & "," & AO & "," & AP & "," & AQ & "," & AR & "," & aAS & ",'" & AT & "'," & AU & "," & AV & "," & AW & "," & AX & "," & AY & "," & AZ & "," & BA & "," & BB & "," & BC & "," & BD & ",'" & BE & "','" & BF & "'," & BG & ",'" & BH & "','" & BI & "'," & BJ & "," & BK & "," & BL & ",'" & BM & "','" & BN & "'"
con.Execute Query
Next
End With
con.Close
Set con = Nothing
Exit Sub
ErrHandler: 'MsgBox "The Not able ta Save Data"
Set con = Nothing
End Sub
The above code is working fine. But it is taking more time to update data.:-(
Now my code became like this
Private Sub Worksheet_Activate()
Dim adoConn As New ADODB.Connection
Dim adoRS As New ADODB.Recordset
Dim sQuery As String
Dim EffectedRecs As Long
Dim sFields As String
Dim sValues As String
Dim iRow As Integer
Dim iField As Integer
ServerName = "193.128.125.14"
con_Str = "Provider=SQLOLEDB; " & _
"Data Source=" & ServerName & "; " & _
"Initial Catalog=DB_At&T;" & _
"User ID=sa; Password=ad28; "
sQuery = "select * from Currency where 1=2"
sValues = ""
With adoConn
.ConnectionString = con_Str
.Provider = "Microsoft.JET.OLEDB.12.0"
.CursorLocation = adUseClient
.Open
End With
With adoRS
.ActiveConnection = adoConn
.CursorLocation = adUseClient
.LockType = adLockBatchOptimistic
.CursorType = adOpenKeyset ' adOpenDynamic
.Source = sQuery
.Open
End With
With ThisWorkbook.Sheets("Export")
For iRow = 3 To ThisWorkbook.Sheets("Export").Range("B65536").End(xlUp).Row
For iField = 0 To adoRS.Fields.Count - 1
sFields = sFields & "," & adoRS.Fields(iField).Name
Next
sValues = sValues & "," & .Range("A" & iRow).Value
sValues = sValues & "," & .Range("B" & iRow).Value
sValues = sValues & "," & .Range("C" & iRow).Value
sValues = sValues & "," & .Range("D" & iRow).Value
sFields = Right(sFields, Len(sFields) - 1) 'Removing ,
sValues = Right(sValues, Len(sValues) - 1) 'Removing ,
adoRS.AddNew FieldList = sFields, Values:=sValues
Next
End With
adoRS.UpdateBatch adAffectAllChapters
adoRS.Close
adoConn.Close
End Sub

you could try this:
Sub InitialExport()
On Error GoTo ErrHandler
'
Dim adoConn As New ADODB.Connection
Dim adoRS As ADODB.Recordset
'
Dim sQuery As String
Dim EffectedRecs As Long
Dim sFields As String
Dim sValues As String
'
Dim iRow As Integer
Dim iField As Integer
'
ServerName = SERVER_NAME
'
sQuery="SELECT * from tableName where 1 =2" ' get an empty recordset!
'
'Set the connection and open
with adoConn
.ConnectionString = CONNECTION_STRING
.Provider = "Microsoft.JET.OLEDB.12.0"
.cursorlocation=aduseclient
.Open
end with
'
' set the Recordset and open
With adoRS
.activeconnection=adoconn
.CursorLocation = adUseClient
.LockType = adLockBatchOptimistic
.CursorType = adopenkeyset ' adOpenDynamic
.Source = sQuery
.Open
End With
'
' now get the data into the recordset
With ThisWorkbook.Sheets("Export")
For iRow = 3 To ThisWorkbook.Sheets("Export").Range("B65536").End(xlUp).Row
' here loop through all the columns
For iField = 0 To adoRS.Fields.Count - 1
' adding the column names to the Variable sFields
sFields = sFields & "," & adoRS.Fields(iField).Name
'
' adding the values from the worksheet for this row
sValues = sValues & ", " & .Cells(iRow, iField).Text
Next
'
' add a new record with the fields and values
adoRS.AddNew FieldList:=sFields, Values:=sValues
'
Next
'
' update all the rows in one step
adoRS.UpdateBatch adAffectAllChapters ' update them all in one step!
'
End Sub
just change tablename in the query to the correct table and make sure the columns in the worksheet are in the same order and datatype as the columns in the table
for ADO Recordset help see:
MSDN Library - ADO Recordset, AddNew method
and
MSDN Library - ADO Recordset, UpdateBatch
and
W3Schools
I hope that get's you started!
Philip

Another option could be uploading your entire Excel Sheet as a csv file directly into the server using BulkInsert.
The Sql code might look as simple as this:
BULK INSERT [DB].[dbo].[Importa_Aux] FROM '\\share\filename.csv' WITH ( FIELDTERMINATOR = ',' , ROWTERMINATOR = '\n' , FIRSTROW = 2 )
Then simply work your data updates in SqlServer.

Related

why datatable change the format of date

In the following code, I am facing an issue such that in SQL the STDATE is stored in datetime2 type, but its format gets changed when called via DataTable in vb.net.
For example: when the date in the database is "2020-02-05 11:32:47.0000000" it changes to #2/5/2020 11:32:47 AM#.
My requirement is to add months and days in the date from the server but when I add the month to it, it adds days instead of months[sic]. So I need the date to be of the same format as in SQL
Dim STDATE As Date
'Dim STDATE1 As String = ""
'Dim STDATE2 As String = ""
Dim STMONTH As Integer
Dim STMONDIFF As Integer
Dim CTY As String = ""
Dim I As Integer
Dim J As Integer
'Dim DPT2 As DateTime = DTP2.Value
CASVW()
Dim CASVWDT As New DataTable
CASVWDT = CASVWDS.Tables(0)
If CASVWDT.Rows.Count > 0 Then
J = CASVWDT.Rows.Count - 1
For I = 0 To J
If CASVWDT.Rows(I)("Case_CaseAbNo").ToString = TB1.Text Then
INSTN = CASVWDT.Rows(I)("Case_NoOfInst").ToString
INSTAMT = CASVWDT.Rows(I)("Case_InstAmt").ToString
STDATE = CASVWDT.Rows(I)("Case_Date")
STMONTH = Month(CASVWDT.Rows(I)("Case_InstStartDate"))
CTY = CASVWDT.Rows(I)("Case_PayType").ToString
End If
Next
End If
STMONDIFF = STMONTH - Month(STDATE)
STDATE = STDATE.AddMonths(STMONDIFF)
'STDATE1 = STDATE.ToString("dd-MM-yyyy 00:00:00")
Dim CBSTR1 As String = "SELECT * FROM TB_CASEINST WHERE CaseInst_CaseUniq='" & CSUNIQ.ToString & "'"
Dim CBDA1 As New SqlDataAdapter(CBSTR1, CN)
Dim CBDT1 As New DataTable
CBDA1.Fill(CBDT1)
CBDA1.Dispose()
If CBDT1.Rows.Count = 0 Then
Dim Z As Integer
Dim INSTSTR As String = ""
Dim CINSTSTR As String = ""
Dim CASEINSTSTR As String = ""
Dim CASEINSTSTR1 As String = ""
Dim CINSTUNIQ As Guid
Dim GURU1 As Long = TB3.Text
Dim GURU2 As Long = TB4.Text
Dim GURU As Long = GURU1 + GURU2
CASEINSTSTR = "INSERT INTO [dbo].[tb_CaseInstD] ([CaseInstDUniq],[CaseInstD_OrgUniq],[CaseInstD_CaseUniq],[CaseInstD_InstUniq],[CaseInstDTranDueDate],[CaseInstDAmt],[CaseInstDBalAmt],[CaseInstDStatus],[CaseInstDRemks],[CaseInstDChqNo],[CaseInstDBankName],[CaseInstDChqDate],[CaseInstDChqAmt],[CaseInstDDate],[CaseInstDIsActive],[CaseInstDTransType],[CaseInstDPAmt],[CaseInstDInttAmt],[CaseInstDType])" _
& "VALUES ('" & Guid.NewGuid().ToString & "','" & ORGUNQ.ToString & "','" & CSUNIQ.ToString & "','" & CSUNIQ.ToString & "','" & STDATE & "'," & TB3.Text & "," & TB3.Text & ",'D','Loan Amount','" & TB6.Text & "','" & CB2.Text & "','" & DTP2.Value.ToString("yyyy-MM-dd HH:mm:ss.fff") & "'," & TB3.Text & ",'" & SRDATE & "','A'," & CASEI & "," & TB3.Text & "," & TB4.Text & ",'L')"
Dim CASEINSTCMD As New SqlCommand(CASEINSTSTR, CN)
CASEINSTCMD.CommandType = CommandType.Text
CASEINSTCMD.ExecuteNonQuery()
CASEINSTCMD.Dispose()
CASEINSTSTR1 = "INSERT INTO [dbo].[tb_CaseInstD] ([CaseInstDUniq],[CaseInstD_OrgUniq],[CaseInstD_CaseUniq],[CaseInstD_InstUniq],[CaseInstDTranDueDate],[CaseInstDAmt],[CaseInstDBalAmt],[CaseInstDStatus],[CaseInstDRemks],[CaseInstDChqNo],[CaseInstDBankName],[CaseInstDChqDate],[CaseInstDChqAmt],[CaseInstDDate],[CaseInstDIsActive],[CaseInstDTransType],[CaseInstDPAmt],[CaseInstDInttAmt],[CaseInstDType])" _
& "VALUES ('" & Guid.NewGuid().ToString & "','" & ORGUNQ.ToString & "','" & CSUNIQ.ToString & "','" & CSUNIQ.ToString & "','" & STDATE & "'," & TB4.Text & "," & GURU & ",'D','Intt Amount','" & TB6.Text & "','" & CB2.Text & "','" & DTP2.Value.ToString("yyyy-MM-dd HH:mm:ss.fff") & "'," & TB3.Text & ",'" & SRDATE & "','A'," & CASEI & "," & TB3.Text & "," & TB4.Text & ",'L')"
Dim CASEINSTCMD1 As New SqlCommand(CASEINSTSTR1, CN)
CASEINSTCMD1.CommandType = CommandType.Text
CASEINSTCMD1.ExecuteNonQuery()
CASEINSTCMD1.Dispose()
I = 0
For Z = 0 To INSTN - 1
If CTY = "M" Then
STDATE = STDATE.AddMonths(I)
'STDATE2 = STDATE.ToString("dd-MM-yyyy 00:00:01")
PAMTPART = Math.Round(TB3.Text / INSTN, 2)
INTAMTPART = Math.Round(TB4.Text / INSTN, 2)
CINSTUNIQ = Guid.NewGuid()
INSTSTR = "INSERT INTO [dbo].[tb_CaseInst] ([CaseInstUniq],[CaseInst_OrgUniq],[CaseInst_CaseUniq],[CaseInstDueDate],[CaseInstAmount], [CaseInstBalAmt],[CaseInstStatus],[CaseInstRemks],[CaseInstDate],[CaseInstPAmt],[CaseInstInttAmt],[IsActive])" _
& "VALUES ('" & CINSTUNIQ.ToString & "','" & ORGUNQ.ToString & "','" & CSUNIQ.ToString & "','" & STDATE & "'," & INSTAMT & "," & INSTAMT & ",'D','Inst. Due','" & SRDATE & "'," & PAMTPART & "," & INTAMTPART & ",'A')"
CINSTSTR = "INSERT INTO [dbo].[tb_CaseInstD] ([CaseInstDUniq],[CaseInstD_OrgUniq],[CaseInstD_CaseUniq],[CaseInstD_InstUniq],[CaseInstDTranDueDate],[CaseInstDAmt],[CaseInstDBalAmt],[CaseInstDStatus],[CaseInstDRemks],[CaseInstDChqNo],[CaseInstDBankName],[CaseInstDChqDate],[CaseInstDChqAmt],[CaseInstDDate],[CaseInstDIsActive],[CaseInstDTransType],[CaseInstDPAmt],[CaseInstDInttAmt],[CaseInstDType])" _
& "VALUES ('" & Guid.NewGuid().ToString & "','" & ORGUNQ.ToString & "','" & CSUNIQ.ToString & "','" & CINSTUNIQ.ToString & "','" & STDATE & "'," & INSTAMT & "," & INSTAMT & ",'D','Inst. Due','XX','XX','" & SRDATE & "',0,'" & SRDATE & "','A'," & CASEI & "," & PAMTPART & "," & INTAMTPART & ",'I')"
I = 1
ElseIf CTY = "D" Then
STDATE = STDATE.AddDays(I)
'STDATE2 = STDATE.ToString("dd-MM-yyyy 00:00:01")
PAMTPART = Math.Round(TB3.Text / INSTN, 2)
CINSTUNIQ = Guid.NewGuid()
INTAMTPART = Math.Round(TB4.Text / INSTN, 2)
INSTSTR = "INSERT INTO [dbo].[tb_CaseInst] ([CaseInstUniq],[CaseInst_OrgUniq],[CaseInst_CaseUniq],[CaseInstDueDate],[CaseInstAmount], [CaseInstBalAmt],[CaseInstStatus],[CaseInstRemks],[CaseInstDate],[CaseInstPAmt],[CaseInstInttAmt],[IsActive])" _
& "VALUES ('" & CINSTUNIQ.ToString & "','" & ORGUNQ.ToString & "','" & CSUNIQ.ToString & "','" & STDATE & "'," & INSTAMT & "," & INSTAMT & ",'D','Inst. Due','" & SRDATE & "'," & PAMTPART & "," & INTAMTPART & ",'A')"
CINSTSTR = "INSERT INTO [dbo].[tb_CaseInstD] ([CaseInstDUniq],[CaseInstD_OrgUniq],[CaseInstD_CaseUniq],[CaseInstD_InstUniq],[CaseInstDTranDueDate],[CaseInstDAmt],[CaseInstDBalAmt],[CaseInstDStatus],[CaseInstDRemks],[CaseInstDChqNo],[CaseInstDBankName],[CaseInstDChqDate],[CaseInstDChqAmt],[CaseInstDDate],[CaseInstDIsActive],[CaseInstDTransType],[CaseInstDPAmt],[CaseInstDInttAmt],[CaseInstDType])" _
& "VALUES ('" & Guid.NewGuid().ToString & "','" & ORGUNQ.ToString & "','" & CSUNIQ.ToString & "','" & CINSTUNIQ.ToString & "','" & STDATE & "'," & INSTAMT & "," & INSTAMT & ",'D','Inst. Due','XX','XX','" & SRDATE & "',0,'" & SRDATE & "','A'," & CASEI & "," & PAMTPART & "," & INTAMTPART & ",'I')"
I = 1
ElseIf CTY = "W" Then
STDATE = STDATE.AddDays(I)
'STDATE2 = STDATE.ToString("dd-MM-yyyy 00:00:01")
PAMTPART = Math.Round((TB3.Text / INSTN), 2) * 7
CINSTUNIQ = Guid.NewGuid()
INTAMTPART = Math.Round((TB4.Text / INSTN), 2) * 7
INSTSTR = "INSERT INTO [dbo].[tb_CaseInst] ([CaseInstUniq],[CaseInst_OrgUniq],[CaseInst_CaseUniq],[CaseInstDueDate],[CaseInstAmount], [CaseInstBalAmt],[CaseInstStatus],[CaseInstRemks],[CaseInstDate],[CaseInstPAmt],[CaseInstInttAmt],[IsActive])" _
& "VALUES ('" & CINSTUNIQ.ToString & "','" & ORGUNQ.ToString & "','" & CSUNIQ.ToString & "','" & STDATE & "'," & INSTAMT & "," & INSTAMT & ",'D','Inst. Due','" & SRDATE & "'," & PAMTPART & "," & INTAMTPART & ",'A')"
CINSTSTR = "INSERT INTO [dbo].[tb_CaseInstD] ([CaseInstDUniq],[CaseInstD_OrgUniq],[CaseInstD_CaseUniq],[CaseInstD_InstUniq],[CaseInstDTranDueDate],[CaseInstDAmt],[CaseInstDBalAmt],[CaseInstDStatus],[CaseInstDRemks],[CaseInstDChqNo],[CaseInstDBankName],[CaseInstDChqDate],[CaseInstDChqAmt],[CaseInstDDate],[CaseInstDIsActive],[CaseInstDTransType],[CaseInstDPAmt],[CaseInstDInttAmt],[CaseInstDType])" _
& "VALUES ('" & Guid.NewGuid().ToString & "','" & ORGUNQ.ToString & "','" & CSUNIQ.ToString & "','" & CINSTUNIQ.ToString & "','" & STDATE & "'," & INSTAMT & "," & INSTAMT & ",'D','Inst. Due','XX','XX','" & SRDATE & "',0,'" & SRDATE & "','A'," & CASEI & "," & PAMTPART & "," & INTAMTPART & ",'I')"
I = 6
Z = Z + 6
If Z >= 100 Then
INSTAMT = INSTAMT - (INSTAMT / 7)
End If
End If
Dim INSTCMD As New SqlCommand(INSTSTR, CN)
INSTCMD.CommandType = CommandType.Text
INSTCMD.ExecuteNonQuery()
INSTCMD.Dispose()
Dim CINSTCMD As New SqlCommand(CINSTSTR, CN)
CINSTCMD.CommandType = CommandType.Text
CINSTCMD.ExecuteNonQuery()
CINSTCMD.Dispose()
Next
This worked for me, might shed some light on your Problem, hope it helps.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim strSQLconn As String = "Your Connectionstring"
Dim sqlConn As New SqlClient.SqlConnection(strSQLconn)
Dim Command As SqlCommand
Command = New SqlCommand("SELECT TOP(1) convert(varchar, [date], 23) FROM [dbo].[Element]", sqlConn)
Dim x As String
sqlConn.Open()
x = Command.ExecuteScalar()
sqlConn.Close()
MessageBox.Show("SQL Date Converted to String: " & x)
Dim d As Date = Date.ParseExact(x, "yyyy-MM-dd", System.Globalization.DateTimeFormatInfo.InvariantInfo)
MessageBox.Show("VB.net string Converted to Date: " & d.ToString)
MessageBox.Show("VB.net string Converted to Date, and an additional 1 month: " & d.AddMonths(1).ToString)
End Sub

Optimizing loop through Access Database

I need help with an massive loop through a continously expanding Access database consisting of approximately 280.000 rows of data. The procedure adds 3000 rows of data every week, and the macros running time is therefore only increasing. It takes around one hour to complete.
What is the optimal way to complete my procedure? I'm experienced with VBA, but SQL knowledge is limited.
The issue summarized is that the If-statement, located in "Help needed here" runs through 280.000 rows of data for 3000 companies.
The goal is that the fresh weekly scores of the company will be scored in JQHistory, but it has to take the date of running the macro into consideration
Note: Everything outside of "Help needed here", I've optimized in another macro. I've left it to hopefully improve the context of the issue.
Here is the non-optimized macro:
Sub OpdaterKvant()
Dim wb As Workbook
Dim ws As Worksheet
Dim DatoIn As Date
Set db = New ADODB.Connection
Set DbEQ = New ADODB.Connection
'The location of the database is determined outside the macro'
strConn = ConnectionString
db.Open strConn
Set wb = Workbooks.Open("My File Location")
Set ws = wb.Worksheets(1)
n = ws.UsedRange.Rows.Count
DateIn = Right(ws.Cells(1, 1), 2) & "-" & Mid(ws.Cells(1, 1), 5, 2) & "-" & Left(ws.Cells(1, 1), 4)
Dato = Format(DateIn, "mm-dd-yyyy")
db.Execute ("DELETE * FROM JQScores")
For i = 3 To n
Sedol = Replace(ws.Cells(i, 1), " ", "")
Company = Left(Replace(ws.Cells(i, 2), "'", ""), Len(Replace(ws.Cells(i, 2), "'", "")) - 1)
Country = Replace(ws.Cells(i, 3), " ", "")
Region = Replace(ws.Cells(i, 4), " ", "")
Sector = Replace(ws.Cells(i, 5), " ", "")
MarketCap = Replace(Replace(ws.Cells(i, 6), " ", ""), ",", ".")
JQRank = Replace(ws.Cells(i, 7), " ", "")
ValueRank = Replace(ws.Cells(i, 8), " ", "")
QualityRank = Replace(ws.Cells(i, 9), " ", "")
MomentumRank = Replace(ws.Cells(i, 10), " ", "")
JQScore = Replace(Replace(ws.Cells(i, 11), " ", ""), ",", ".")
'Inserts the information into the Access database.'
Sql = "Insert into JQScores (Sedol, Company, Region, Sector, MarketCapUSD, JQ_Rank, Value_Rank, Quality_Rank, Momentum_Rank, JQ_Score, Country) VALUES ('" & Sedol & "','" & Company & "', '" & Region & "', '" & Sector & "', " & MarketCap & ", '" & JQRank & "', '" & ValueRank & "', '" & QualityRank & "', '" & MomentumRank & "', " & JQScore & ", '" & Country & "')"
db.Execute (Sql)
'*** HELP NEEDED IN THIS SECTION'
If db.Execute("Select Count(Id) as NumId from JQHistory where Sedol='" & Sedol & "' and history_date=#" & Dato & "#")("NumId") = 0 Then
Sql = "Insert into JQHistory (History_date, Sedol, Selskabsnavn, JQScore, JQ_Rank, Value_Rank, Momentum_Rank, Quality_Rank, Marketcap) VALUES (#" & Dato & "#, '" & Sedol & "','" & Company & "'," & JQScore & ", '" & JQRank & "', '" & ValueRank & "', '" & MomentumRank & "', '" & QualityRank & "', " & MarketCap & ")"
db.Execute (Sql)
Else
Sql = "Update JQHistory set MarketCap=" & MarketCap & ", Selskabsnavn='" & Company & "' , JQ_Rank='" & JQRank & "', Value_Rank='" & ValueRank & "', Quality_Rank='" & QualityRank & "', Momentum_Rank='" & MomentumRank & "', JQScore=" & JQScore & " WHERE SEDOL='" & Sedol & "' and History_Date=#" & Dato & "#"
db.Execute (Sql)
End If
'***'
Next i
db.Close
wb.Close
The optimal way ended up using the DAO.Recordset and DAO.Database options, and a lot of tweaks for optimization.
The biggest shortcut was using the 'Recordset.FindFirst' to identify if the data should only be added (takes 22 seconds), or update the data with identical date (takes 12 minutes). Although mainly the scenario taking 22 seconds will happen.
The scenario taking 12 minutes is not optimized since it rarely happens.
Full solution:
Sub OpdaterKvant()
Dim wb As Workbook
Dim wbOp As Workbook
Dim ws As Worksheet
Dim wsOp As Worksheet
Dim i, n As Integer
Dim db As DAO.Database
Dim rsScores As DAO.Recordset
Dim rsHistory As DAO.Recordset
StartTime = Timer
Call PERFORMANCEBOOST(False)
Set PB = CREATEPROGRESSBAR
With PB
.SetStepCount (4)
.Show
End With
Set wbOp = ThisWorkbook
Set wsOp = wbOp.ActiveSheet
'Step 1: Open JQGCLE
Set wb = Workbooks.Open("Location", ReadOnly:=True)
Set ws = wb.Worksheets(1)
ws.Activate
n = ws.UsedRange.Rows.Count
DateIn = Right(ws.Cells(1, 1), 2) & "-" & Mid(ws.Cells(1, 1), 5, 2) & "-" & Left(ws.Cells(1, 1), 4)
'Step 2: Optag værdier i Excel
PB.Update "Data hentes fra JQGLCE-ark"
ReDim Sedol(3 To n) As String
ReDim Company(3 To n) As String
ReDim Country(3 To n) As String
ReDim Region(3 To n) As String
ReDim Sector(3 To n) As String
ReDim MarketCap(3 To n) As String 'Tal
ReDim MarketCapSQL(3 To n) As String 'Tal
ReDim JQRank(3 To n) As String
ReDim ValueRank(3 To n) As String
ReDim QualityRank(3 To n) As String
ReDim MomentumRank(3 To n) As String
ReDim JQScore(3 To n) As String 'Tal
ReDim JQScoreSQL(3 To n) As String 'Tal
For i = 3 To n
Sedol(i) = Trim(ws.Cells(i, 1))
Company(i) = Left(Replace(ws.Cells(i, 2), "'", ""), Len(Replace(ws.Cells(i, 2), "'", "")) - 0) 'Stod tidligere på minus 1 - Hvorfor?
Country(i) = Trim(ws.Cells(i, 3))
Region(i) = Trim(ws.Cells(i, 4))
Sector(i) = Trim(ws.Cells(i, 5))
MarketCap(i) = ws.Cells(i, 6) 'Til DAO
MarketCapSQL(i) = Replace(ws.Cells(i, 6), ",", ".") 'Til SQL
JQRank(i) = Trim(ws.Cells(i, 7))
ValueRank(i) = Trim(ws.Cells(i, 8))
QualityRank(i) = Trim(ws.Cells(i, 9))
MomentumRank(i) = Trim(ws.Cells(i, 10))
JQScore(i) = ws.Cells(i, 11) 'Til DAO
JQScoreSQL(i) = Replace(ws.Cells(i, 11), ",", ".") 'Til SQL
'DAO og SQL bliver behandlet forskelligt ift. komma
Next i
'Step 3: Indsæt værdier i Access-database
Set acc = New Access.Application
Set db = acc.DBEngine.OpenDatabase("Location", 1, 0)
'Step 3.1: JQScores
PB.Update "JQScores indsættes i databasen"
Set rsScores = db.OpenRecordset(Name:="JQScores", Type:=RecordsetTypeEnum.dbOpenDynaset)
db.Execute "DELETE * FROM JQScores"
For i = 3 To n
With rsScores
.AddNew
!Sedol = Sedol(i)
!Company = Company(i)
!Region = Region(i)
!Sector = Sector(i)
!MarketCapUSD = MarketCap(i)
!JQ_Rank = JQRank(i)
!Value_Rank = ValueRank(i)
!Quality_Rank = QualityRank(i)
!Momentum_Rank = MomentumRank(i)
!JQ_Score = JQScore(i)
!Country = Country(i)
.Update
End With
Next i
rsScores.Close
Set rsScores = Nothing
'Step 3.2: JQHistory
Set rsHistory = db.OpenRecordset(Name:="JQHistory", Type:=RecordsetTypeEnum.dbOpenDynaset)
With rsHistory
If .RecordCount <> 0 Then
i = 3
.FindFirst "History_Date = '" & DateIn & "'"
If .NoMatch = True Then
'Hvis datoen ikke er i datasættet, bliver dataen tilføjet
PB.Update "Hurtig: JQHistory indsættes i databasen"
For i = 3 To n
.AddNew
!History_Date = DateIn
!Sedol = Sedol(i)
!Selskabsnavn = Company(i)
!MarketCap = MarketCap(i)
!JQ_Rank = JQRank(i)
!Value_Rank = ValueRank(i)
!Quality_Rank = QualityRank(i)
!Momentum_Rank = MomentumRank(i)
!JQScore = JQScore(i)
.Update
Next i
Else
'Hvis datoen allerede er der, skal den opdateres
PB.Update "Langsom: JQHistory indsættes i databasen"
For i = 3 To n
db.Execute ("UPDATE JQHistory SET MarketCap=" & MarketCapSQL(i) & ", Selskabsnavn='" & Company(i) & "', JQ_Rank='" & JQRank(i) & "', Value_Rank='" & ValueRank(i) & "', Quality_Rank='" & QualityRank(i) & "', Momentum_Rank='" & MomentumRank(i) & "', JQScore=" & JQScoreSQL(i) & " WHERE SEDOL='" & Sedol(i) & "' and History_Date='" & DateIn & "'")
Next i
End If
End If
End With
rsHistory.Close
Set rsHistory = Nothing
'Step 4: Færdiggørelse
acc.DoCmd.Quit acQuitSaveAll 'Lukker og gemmer database
Set db = Nothing
wsOp.Activate
wsOp.Range("B7").Value = "Seneste data benyttet: " & DateIn
wb.Close SaveChanges:=False
Call PERFORMANCEBOOST(True)
Unload PB
MinutesElapsed = Format((Timer - StartTime) / 86400, "hh:mm:ss")
MsgBox "Opdatering fuldført. Proceduren tog " & MinutesElapsed & "."
End Sub

Loop through range and insert values into SQL Table

A set of data in Excel looking like this:
Test1 12345678 1906 John GY DFS H1C Y
Test2 12345678 1806 Jack GY GQ H1C Y
Test3 12345678 1706 Kate GY GQ H1C Y
Test4 12345678 1606 Sawyer GY GQ H1C
The very last column is to check if data was already loaded to SQL Server.
I have written code to iterate through range and insert values into SQL Table. Within this code, it also checks that last column, if there is a Y, it should skip iteration and go to the next one..
It gives me an error, saying "Else without if".
Sub Connection()
Dim Conn As ADODB.Connection
Dim Command As ADODB.Command
Set Conn = New ADODB.Connection
Set Command = New ADODB.Command
Dim i As Integer
Dim rownumber As Integer
rownumber = Sheets("Sheet1").Range("A1048576").End(xlUp).Row
Conn.ConnectionString = "Provider=SQLOLEDB; Data Source=[Server];Initial Catalog=[DB];User ID=[user];Password=[Password]; Trusted_Connection=no"
Conn.Open
Command.ActiveConnection = Conn
For i = 1 To rownumber 'rows
If ActiveSheet.Cells(i, 8).Value = "Y" Then GoTo NextIteration
Else
Command.CommandText = "INSERT INTO [Database] (" & _
"[Col1], [Col2], [Col3], [Col4], [Col5], [Col6], [Col7])" & _
"VALUES (" & _
"'" & ActiveSheet.Cells(i, 1).Value & "'," & _
"'" & ActiveSheet.Cells(i, 2).Value & "'," & _
"'" & ActiveSheet.Cells(i, 3).Value & "'," & _
"'" & ActiveSheet.Cells(i, 4).Value & "'," & _
"'" & ActiveSheet.Cells(i, 5).Value & "'," & _
"'" & ActiveSheet.Cells(i, 6).Value & "'," & _
"'" & ActiveSheet.Cells(i, 7).Value & "')"
Command.Execute
ActiveSheet.Cells(i, 8).Value = "Y"
End If
Next i
Conn.Close
Set Conn = Nothing
End Sub
I am really struggling to figure out where I went wrong. The code works perfectly fine without checking if "Y" is there...
I appreciate your help.
Try the following
Use Option Explicit at the top to check for variable declarations
Use Long not Integer to avoid potential overflow as you are working with numbers of rows which can exceed capacity of Integer
If statement needs to be broken over several lines to function with Else
Your GoTo referenced a label, NextIteration, which needed adding, You need to verify this is now in the correct place.
Avoid calling your sub connection and use something less ambiguous for the compiler
Public Sub My_Connection()
Dim Conn As ADODB.Connection
Dim Command As ADODB.Command
Set Conn = New ADODB.Connection
Set Command = New ADODB.Command
Dim i As Long
Dim rownumber As Long
rownumber = Worksheets("Sheet1").Range("A1048576").End(xlUp).Row
Conn.ConnectionString = "Provider=SQLOLEDB; Data Source=[Server];Initial Catalog=[DB];User ID=[user];Password=[Password]; Trusted_Connection=no"
Conn.Open
Command.ActiveConnection = Conn
For i = 1 To rownumber 'rows
If ActiveSheet.Cells(i, 8).Value = "Y" Then
GoTo NextIteration
Else
Command.CommandText = "INSERT INTO [Database] (" & _
"[Col1], [Col2], [Col3], [Col4], [Col5], [Col6], [Col7])" & _
"VALUES (" & _
"'" & ActiveSheet.Cells(i, 1).Value & "'," & _
"'" & ActiveSheet.Cells(i, 2).Value & "'," & _
"'" & ActiveSheet.Cells(i, 3).Value & "'," & _
"'" & ActiveSheet.Cells(i, 4).Value & "'," & _
"'" & ActiveSheet.Cells(i, 5).Value & "'," & _
"'" & ActiveSheet.Cells(i, 6).Value & "'," & _
"'" & ActiveSheet.Cells(i, 7).Value & "')"
Command.Execute
ActiveSheet.Cells(i, 8).Value = "Y"
End If
NextIteration:
Next i
Conn.Close
Set Conn = Nothing
End Sub
Add a new line after 'Then' on the first if statement or elses vba implicity closes the if statement.

Error 3075 When breaking down long text for update query

The Description field is a long text field with over 255 characters. so I'm trying to break it down before I update it. My error reads:
Run-Time error '3075 Syntax error (missing Operator) in query
expression "titlename'Set Description = '([prm_val1] &
[prm_val2].....[prm_val7])".
Here's my code:
l = Len(Me.Description)
If l Mod 255 = 0 Then 'For length exactly a multiple of 255 (255, 510, 765...)
n = l / 255
Else
n = Int(l / 255) + 1
End If
sp = "[prm_val1]"
If n > 1 Then 'If >255 chars tap on concatenated parameters as needed
For p = 2 To n
sp = sp & " & [prm_val" & p & "]"
Next p
End If
'UpdateDescription = "UPDATE AllProjects " & _
'"Set Description='" & sp & "'" & _
'" WHERE ID =" & Me.ID
'CurrentDb.Execute UpdateDescription
'For p = 1 To n 'Add each 255 char piece as the parameters
'qdf.Parameters("prm_val" & p) = Mid(varValue, (p - 1) * 255 + 1, 255)
'Next p
'qdf.Execute
DoCmd.SetWarnings False
strSQL = "UPDATE AllProjects " & _
"Set Title='" & Me.Title & "'" & _
"Set Description='(" & sp & ")'" & _
",Department='" & Me.Department & "'" & _
",Priority='" & Me.Priority & "'" & _
",Status='" & Me.Status & "'" & _
",[Create Date]='" & Me.CreateDate & "'" & _
",[% Complete]='" & Me.PerComplete & "'" & _
",[File Location]='" & Me.FileLocation & "'" & _
",[Update Notes]='" & Me.UpdateNotes & "'" & _
",Leader='" & Me.Leader & "'" & _
",[Target Date]='" & Me.TargetDate & "'" & _
",[Complete Date]='" & Me.CompleteDate & "'" & _
",Category='" & Me.Category & "'" & _
",Feedback='" & Me.Feedback & "'" & _
",[File Location 2]='" & Me.FileLocation2 & "'" & _
",[File Location 3]='" & Me.FileLocation3 & "'" & _
",[Strategic Initiatives]='" & Me.StrategicInitiatives & "'" & _
" WHERE ID =" & Me.ID
CurrentDb.Execute strSQL
For p = 1 To n 'Add each 255 char piece as the parameters
strSQL.Parameters("prm_val" & p) = Mid(varValue, (p - 1) * 255 + 1, 255)
Next p
DoCmd.SetWarnings True
This code is called after the execute, and does not make any sense:
For p = 1 To n 'Add each 255 char piece as the parameters
strSQL.Parameters("prm_val" & p) = Mid(varValue, (p - 1) * 255 + 1, 255)
Next p
as strSQL doesn't take parameters.
Adjust this code and move it inte the code before calling execute.
Or use the query you have commented out.

Excel and MS Access: Method 'open' of object '_Recordset' failed

I am writing this code in Excel to insert into an access database.
INSERT INTO `C:\Users\ABCBASDkJAJDSKk\Desktop\asdgahsdguu.accdb`.`Table1` Values ('ABCD', 'ABCD','ABCD,ABCD','NA','Success','Several of the above','NA','NA','NA','NA','NA','NA','NA','AB',12)
I am getting the error Method open of object Recordset failed at the rs.open statement.
Any thoughts on why this is happening?
Below is the code
Sub merge_update()
Dim ws As Worksheet
Set ws = Sheets("Darwin Merge Set")
lastrow = ws.Range("B" & Rows.count).End(xlUp).Row
Dim cmd1 As ADODB.Command
Application.ScreenUpdating = False
Dim i As Integer
Dim cn As ADODB.Connection
Set cn = New Connection
strFile = "C:\Users\ABCBASDkJAJDSKk\Desktop\asdgahsdguu.accdb"
cn.Provider = " Provider=Microsoft.ACE.OLEDB.15.0 "
cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.15.0;Data Source=" & strFile & ";Persist Security Info=false;"
Dim rs As New ADODB.Recordset
cn.Open
For i = 7 To lastrow
src = Range("b" & i).Value
tar = Range("c" & i).Value
dmc = Range("d" & i).Value
gl = Range("e" & i).Value
mo = Range("f" & i).Value
msa = Range("g" & i).Value
fm = Range("h" & i).Value
rsnm = Range("i" & i).Value
em = Range("j" & i).Value
sa = Range("k" & i).Value
rbsc = Range("l" & i).Value
qao = Range("m" & i).Value
qac = Range("n" & i).Value
lo = Range("o" & i).Value
mpl = Range("p" & i).Value
mon = Range("q" & i).Value
stmt = "INSERT INTO `" & strFile & "`.`Table1`"
stmt = stmt & " Values ('" & src & "', '" & tar & "','" & dmc & "','" & gl & "','" & mo & "','" & msa & "','" & fm & "','" & rsnm & "','" & em & "','" & sa & "','" & rbsc & "','" & qao & "','" & qac & "','" & mpl & "'," & mon & ") "
cmd1.ActiveConnection = cn
cmd1.CommandText = stmt
Set rs = cmd1.Execute
Next i
cn.Close
End Sub
You aren't using a command object, you want to replace the RecordSet with a Command. The recordset is where the values come back from the database.
here is a link with a lot of good examples for you.
http://support.microsoft.com/kb/168336/en-us
One example (the New in the Dim cmd1 line is important.
Dim cmd1 As New ADODB.Command
' Recordset Open Method #2: Open via Command.Execute(...)
Conn1.ConnectionString = AccessConnect
Conn1.Open
Cmd1.ActiveConnection = Conn1
Cmd1.CommandText = "SELECT * FROM Employees"
Set Rs1 = Cmd1.Execute
Rs1.Close
Conn1.Close
Conn1.ConnectionString = ""