I have a excel workbook that pulls data into a table users can then fill in the missing dates in column 11. Column 1 is the unique identifier that matches the ID column in the SQL table. I want to create a macro that runs when the workbook is closed and will update the SQL table with the filled in dates, but I am struggling with the code. I have have tried two different things but neither seem to work.
Option 1:
Private Sub tableupdate()
Dim con As New ADODB.Connection
Dim cmd As New ADODB.Command
Dim rst As New ADODB.Recordset
Dim i As Long
Dim vDB As Variant
Dim ws As Worksheet
con.connectionstring = "Provider=SQLOLEDB;Password=*********;User ID=clx_write; Initial Catalog=DPEDataMartDBPrd01; Data Source=tcp:dscusnoramcloroxprd01.database.windows.net,1433;"
con.Open
Set cmd.ActiveConnection = con
Set ws = ActiveSheet
vDB = ws.Range("A4").CurrentRegion
For i = 2 To UBound(vDB, 1)
cmd.CommandText = "UPDATE [dbo].[all_load_control] set Driver_arr_dte = ' " & vDB(i, 2) & " ' WHERE mst_ship_num = ' " & vDB(i, 1) & " ' "
cmd.Execute
Next i
con.Close
Set con = Nothing
End Sub
option 2:
Private Sub uplodblanks()
Dim r, c, con, dstring
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim lRow
Dim ssql As String
con = "Provider=SQLOLEDB;Password=********;User ID=clx_write; Initial Catalog=DPEDataMartDBPrd01; Data Source=tcp:dscusnoramcloroxprd01.database.windows.net,1433;"
r = 1
c = 1
Worksheets("WTUpload").Calculate
lRow = Cells.Find(What:="*", After:=Range("A1"), LookAt:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False).Row
cn.Open con
i = 1
For i = 1 To lRow
ssql = "update dbo.cxu_all_load_control set driver_arr_dte = " & CDate(Sheets("WTUpload").Cells(i, 11)) & " where mst_ship_num = " & CDbl(Sheets("WTUpload").Cells(i, 11)) & " ; "
cn.Execute ssql
Next i
cn.Close
End Sub
Any help as to why neither of these are working would be great
Replace the mydbConnect() function with you own method of getting a connection.
Sub tableupdate2()
Const COL_NUM As String = "A"
Const COL_DATE As String = "K"
Const TABLE As String = "dbo.all_load_control"
' define update sql
Const SQL As String = " UPDATE " & TABLE & _
" SET Driver_arr_dte = CAST(? AS DATETIME2) " & _
" WHERE mst_ship_num = ? "
' establish connection and create command object
Dim con As Object, cmd As Object, sSQL As String
Set con = mydbConnect() ' establish connection
Set cmd = CreateObject("ADODB.Command")
With cmd
.ActiveConnection = con
.CommandText = SQL
.CommandType = 1 'adCmdText
.Parameters.Append .CreateParameter("P1", adVarChar, 1, 20) '
.Parameters.Append .CreateParameter("P2", adVarChar, 1, 50) ' adParamInput = 1
End With
' prepare to get data from spreadsheet
Dim wb As Workbook, ws As Worksheet, iLast As Integer, iRow As Integer
Set wb = ThisWorkbook
Set ws = wb.Sheets("WTUpload")
iLast = ws.Range(COL_NUM & Rows.count).End(xlUp).Row
Dim p1 As String, p2 As String, count As Long
' scan sheet and update db
Debug.Print "Updates " & Now
With cmd
For iRow = 1 To iLast
p1 = Format(ws.Range(COL_DATE & iRow).Value, "yyyy-mm-dd hh:mm")
p2 = ws.Range(COL_NUM & iRow).Value
If len(p2) > 0 Then
.Parameters(0).Value = p1
.Parameters(1).Value = p2
Debug.Print "Row ", iRow, "p1=" & p1, "P2=" & p2
.Execute
count = count + 1
End If
Next
End With
' end
MsgBox "Rows processed = " & count, vbInformation, "Updates Complete"
con.Close
Set con = Nothing
End Sub
Edit - added connection and test code
Function mydbConnect() As Object
Dim sConStr As String
sConStr = "Provider=SQLOLEDB;Password=*********;User ID=clx_write;" & _
"Initial Catalog=DPEDataMartDBPrd01;" & _
"Data Source=tcp:dscusnoramcloroxprd01.database.windows.net,1433;"
Set mydbConnect = CreateObject("ADODB.Connection")
mydbConnect.Open sConStr
End Function
Sub test()
Dim con As Object, rs As Object
Set con = mydbConnect()
Set rs = con.Execute("SELECT CURRENT_TIMESTAMP")
MsgBox rs.Fields(0), vbInformation, "Current Date/Time"
End Sub
Related
I have a data table that has just a few columns: GLID, Metric Category, Amount, and Metric Date. The way the data is organized on the excel file I need to use is like a matrix as so:
The date columns are the metric date and the numbers below them are the amounts. As you can see for each date there is some amount that pertains to a particular metric category and in some cases a GLID. Now what I need to do in VBA is push the data into the format as so
GLID Metric Category Amount Metric Date
5500 Property Tax-5500 -8 3/31/2020
5500 Property Tax-5500 -8 4/30/2020
So on and so forth. I am completely new to VBA so this particular task is daunting and challenging for me and thus why I made a post here. If anyone has some suggestions I would greatly appreciate it.
So far this is the setup I have in VBA:
Sub second_export()
Dim sSQL As String, sCnn As String, sServer As String
Dim db As Object, rs As Object
sServer = "CATHCART"
sCnn = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=Portfolio_Analytics;Data Source=" & sServer & ";" & _
"Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;"
Set db = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
If db.State = 0 Then db.Open sCnn
End Sub
Note For Further Clarification:
The number of columns is 36 and the number of rows is 46 in the excel file. For the categories that do not have a GLID then we can push NULL if needed.
I can push data into the database when its simply and insert but I have to pivot the data such that the GLID and Metric category are repeated for their associated dates and amounts.
First create a sheet of data to upload
Option Explicit
Sub CreateDataSheet()
Dim wb As Workbook, ws As Worksheet, wsData As Worksheet, header As Variant
Dim iLastRow, iLastCol, dt As Variant, iOutRow
Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet1") ' the matrix sheet
Set wsData = wb.Sheets("Sheet2") ' sheet to hold table data
wsData.Cells.Clear
wsData.Range("A1:D1") = Array("GLID", "Metric Category", "Amount", "Metric Date")
' get header
iLastCol = ws.Cells(1, Columns.Count).End(xlToLeft).Column
iLastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
header = ws.Range(ws.Cells(1, 3), ws.Cells(1, iLastCol))
'Debug.Print iLastRow, iLastCol, UBound(header, 2)
Dim r, c
iOutRow = 2
For r = 2 To iLastRow
For c = 1 To UBound(header, 2)
'Debug.Print r, header(1, c), ws.Cells(r, c + 2)
With wsData.Cells(iOutRow, 1)
.Offset(0, 0) = ws.Cells(r, 1)
.Offset(0, 1) = ws.Cells(r, 2)
.Offset(0, 2) = ws.Cells(r, c + 2)
.Offset(0, 3) = header(1, c)
End With
iOutRow = iOutRow + 1
Next
Next
wsData.Range("A1").Select
MsgBox iOutRow - 2 & " Rows created on " & wsData.Name, vbInformation
End Sub
Then create a table in the database
Sub CreateTable()
Const TABLE_NAME = "dbo.GL_TEST"
Dim SQL As String, con As Object
SQL = "CREATE TABLE " & TABLE_NAME & "( " & vbCr & _
"RECNO int NOT NULL," & vbCr & _
"GLID nchar(10)," & vbCr & _
"METRICNAME nvarchar(255)," & vbCr & _
"AMOUNT money," & vbCr & _
"METRICDATE date," & vbCr & _
"PRIMARY KEY (RECNO))"
'Debug.Print sql
Set con = mydbConnect()
'con.Execute ("DROP TABLE " & TABLE_NAME) ' use during testing
con.Execute SQL
con.Close
Set con = Nothing
MsgBox "Table " & TABLE_NAME & " created"
End Sub
using data connection.
Function mydbConnect() As Object
Dim sConStr As String
Const sServer = "CATHCART"
sConStr = "Provider=SQLOLEDB.1;" & _
"Integrated Security=SSPI;" & _
"Persist Security Info=True;" & _
"Initial Catalog=Portfolio_Analytics;" & _
"Data Source=" & sServer & ";" & _
"Use Procedure for Prepare=1;" & _
"Auto Translate=True;Packet Size=4096;"
Set mydbConnect = CreateObject("ADODB.Connection")
mydbConnect.Open sConStr
End Function
Then load the data from the sheet one record at a time with auto-commit off.
Sub LoadData()
Const TABLE_NAME = "dbo.GL_TEST"
Dim SQL As String
SQL = " INSERT INTO " & TABLE_NAME & _
" (RECNO,GLID,METRICNAME,AMOUNT,METRICDATE) VALUES (?,?,?,?,?) "
Dim con As Object, cmd As Object, rs As Variant
Set con = mydbConnect()
Set cmd = CreateObject("ADODB.Command")
With cmd
.ActiveConnection = con
.CommandType = adCmdText
.CommandText = SQL
.Parameters.Append .CreateParameter("P1", adInteger, adParamInput)
.Parameters.Append .CreateParameter("P2", adVarWChar, adParamInput, 10)
.Parameters.Append .CreateParameter("P3", adVarWChar, adParamInput, 255)
.Parameters.Append .CreateParameter("P4", adCurrency, adParamInput)
.Parameters.Append .CreateParameter("P5", adDate, adParamInput)
End With
con.Execute "SET IMPLICIT_TRANSACTIONS ON"
Dim ws As Worksheet, iLastRow As Long, i As Long
Set ws = ThisWorkbook.Sheets("Sheet2") ' sheet were table data is
iLastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To iLastRow
cmd.Parameters(0).Value = i
cmd.Parameters(1).Value = ws.Cells(i, 1)
cmd.Parameters(2).Value = ws.Cells(i, 2)
cmd.Parameters(3).Value = ws.Cells(i, 3)
cmd.Parameters(4).Value = ws.Cells(i, 4)
cmd.Execute
Next
con.Execute "COMMIT"
con.Execute "SET IMPLICIT_TRANSACTIONS OFF"
rs = con.Execute("SELECT COUNT(*) FROM " & TABLE_NAME)
MsgBox rs(0) & " Rows are in " & TABLE_NAME, vbInformation
con.Close
Set con = Nothing
End Sub
Here's how you can loop over your data:
Sub Tester()
Dim rw As Range, n As Long
Dim GLID, category, dt, amount
For Each rw In ActiveSheet.Range("H2:AS47").Rows
'fixed per-row
GLID = Trim(rw.Cells(1).Value)
category = Trim(rw.Cells(2).Value)
'loopover the date columns
For n = 3 To rw.Cells.Count
dt = rw.Cells(n).EntireColumn.Cells(1).Value 'date from Row 1
amount = rw.Cells(n).Value
Debug.Print rw.Cells(n).Address, GLID, category, amount, dt
'insert a record using your 4 values
'switch GLID to null if empty
Next n
Next rw
End Sub
I'm using the code below to import tables from SQL Server into Excel.
So the old data be removed and new be inserted. I need to insert table to related data. I find something called ListObject but I didn't know how to apply it. Is there any way to insert table after the data are inserted?
Option Explicit
Dim conn As ADODB.Connection
Dim rst As ADODB.Recordset
Sub Connect_To_SQLServer(ByVal Server_Name As String, ByVal Database_Name As String, ByVal SQL_Statement As String)
Dim strConn As String
Dim wsReport As Worksheet
Dim col As Integer
Dim tbl As ListObject
strConn = "Provider=SQLOLEDB;"
strConn = strConn & "Server=" & Server_Name & ";"
strConn = strConn & "Database=" & Database_Name & ";"
strConn = strConn & "Trusted_Connection=yes;"
Set conn = New ADODB.Connection
With conn
.Open ConnectionString:=strConn
.CursorLocation = adUseClient
End With
Set rst = New ADODB.Recordset
With rst
.ActiveConnection = conn
.Open Source:=SQL_Statement
End With
'// here i selected the sheet where the data will be written
Set wsReport = Sheets("RDWH")
With wsReport
'// here I clear the old data and insert new set
wsReport.Select
Selection.Clear
For col = 0 To rst.Fields.Count - 1
.Cells(1, col + 1).Value = rst.Fields(col).Name
Next col
.Range("A2").CopyFromRecordset rst
End With
Set wsReport = Nothing
Call Close_Connections
End Sub
Private Sub Close_Connections()
If rst.State <> 0 Then rst.Close
If conn.State <> 0 Then conn.Close
'// Release Memory
Set rst = Nothing
Set conn = Nothing
End Sub
Sub Run_Report()
Dim Server_Name As String
Server_Name = "NL-1012716\SQLEXPRESS"
Call Connect_To_SQLServer(Server_Name, "project", "SELECT * FROM [2_RDWH_CAST]")
End Sub
It is easier if the sheet name matches the table name and just delete any sheet with that name. Then recreate the sheet with a new table. This example shows how multiple tables can be downloaded in one operation with each query creating a new sheet.
-- Update ; Added sheet name and position parameters to sub Run_Report.
Option Explicit
Sub Run_Reports()
Dim conn As ADODB.Connection
Const SERVER_NAME As String = "NL-1012716\SQLEXPRESS"
Const DB_NAME = "test"
Dim sTable As String
sTable = ThisWorkbook.Sheets("Control").Range("H6").Value
' connect to DB, run reports and disconnect
Set conn = Connect_To_SQLServer(SERVER_NAME, DB_NAME)
Call Run_Report(conn, sTable, "Sheet3", "A3")
conn.Close
Set conn = Nothing
End Sub
Sub Run_Report(ByRef conn As ADODB.Connection, ByVal TABLE_NAME As String, _
SHEET_NAME As String, START_CELL As String)
If Len(TABLE_NAME) = 0 Then
MsgBox "TABLE_NAME missing", vbCritical, "ERROR"
Exit Sub
End If
Dim rst As ADODB.Recordset
Dim wb As Workbook, ws As Worksheet, i As Integer
Dim wsReport As Worksheet, tblResult As ListObject
' query
Dim SQL As String
SQL = "SELECT * FROM [" & TABLE_NAME & "]"
' execute query
Set rst = New ADODB.Recordset
With rst
.ActiveConnection = conn
.Open Source:=SQL
End With
' output
Set wb = ThisWorkbook
' clear sheet
Set wsReport = wb.Sheets(SHEET_NAME)
wsReport.Cells.Clear
With wsReport.Range(START_CELL)
' write headers
For i = 0 To rst.Fields.Count - 1
.Offset(0, i).Value = rst.Fields.Item(i).Name
Next
' write data
.Offset(1, 0).CopyFromRecordset rst
' create table
Set tblResult = wsReport.ListObjects.Add(xlSrcRange, .CurrentRegion, , xlYes)
' add table name
.Offset(-1, 0) = TABLE_NAME
End With
MsgBox "Rows written = " & rst.RecordCount, vbInformation, TABLE_NAME
rst.Close
Set rst = Nothing
End Sub
Function Connect_To_SQLServer(SERVER_NAME As String, DB_NAME As String) As ADODB.Connection
Dim strConn As String
strConn = "Provider=SQLOLEDB;" & _
"Server=" & SERVER_NAME & ";" & _
"Database=" & DB_NAME & ";" & _
"Trusted_Connection=yes;"
Set Connect_To_SQLServer = New ADODB.Connection
With Connect_To_SQLServer
.Open ConnectionString:=strConn
.CursorLocation = adUseClient
End With
End Function
I have used below code but failed at step
ActiveWorkbook.Sheets("Sheet1").Cells.CopyFromRecordset rs
Can anyone help to check why?
Sub get_Data_From_DB()
Dim cnn As ADODB.Connection
Set cnn = New ADODB.Connection
' Open a connection by referencing the ODBC driver.
cnn.ConnectionString = "driver={SQL Server};" & _
"server=aaaaa,2431;uid=bbb;pwd=ccc;database=ddd"
cnn.Open
' Find out if the attempt to connect worked.
If cnn.State = adStateOpen Then
MsgBox "Welcome to Pubs!"
Sql = "SELECT top 10 * from tableA(NOLOCK)"
Set rs = cnn.Execute(Sql)
ActiveWorkbook.Sheets("Sheet1").Cells.CopyFromRecordset rs
Else
MsgBox "Sorry. No Pubs today."
End If
' Close the connection.
cnn.Close
End Sub
Change this:
ActiveWorkbook.Sheets("Sheet1").Cells.CopyFromRecordset rs
To something like this:
ActiveWorkbook.Sheets("Sheet1").Range("A1").CopyFromRecordset rs
You can change "A1" to another cell if you'd like.
EDIT: Here's how I'd actually organize this to make it flexible/reusable.
Sub runPubsQuery
Dim sqlStr As String
sqlStr = "SELECT top 10 * FROM tableA(NOLOCK)"
Call writeSqlResults(sqlStr,getConnectionString(),ThisWorkbook.Sheets("Sheet1"))
End Sub
Sub writeSQLResults(sqlStr As String, connStr As String, destWS As Worksheet, _
Optional errMsg As String = "Sorry. No Pubs today.", Optional welcMsg As String = "Welcome to Pubs!")
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim headerArr As Variant
cn.Open (connStr)
If Not cn.State = adStateOpen Then
MsgBox errMsg
Else
MsgBox welcMsg
Set rs = cn.Execute(sqlStr)
If Not rs.EOF Then
headerArr = getRecordHeaders(rs)
With destWS
.Cells.Clear
.Range(.Cells(1, 1), .Cells(1, UBound(headerArr, 2))).Value = headerArr
.Range("A2").CopyFromRecordset rs
End With
rs.Close
End If
End If
cn.Close
End Sub
Function getConnectionString(Optional serverName As String = "aaaa,2431", Optional dbName As String = "ddd", _
Optional uidStr As String = "bbb", Optional pwdStr As String = "ccc") As String
getConnectionString = "Driver={SQL Server};" & _
"Server=" & serverName & ";" & _
"Uid=" & uidStr & ";" & _
"Pwd=" & pwdStr & ";" & _
"Database=" & dbName & ";"
End Function
Function getRecordHeaders(rs As Variant) As Variant
If Not TypeName(rs) = "Recordset" Then
MsgBox "Error: Parameter rs is not a valid recordset"
Stop
Exit Function
End If
Dim i As Long
Dim j As Long
If Not rs.EOF Then
ReDim headerArr(1 To 1, 1 To rs.Fields.Count) As Variant
j = 0
For i = LBound(headerArr, 2) To UBound(headerArr, 2)
headerArr(1, i) = rs.Fields(j).Name
j = j + 1
Next
getRecordHeaders = headerArr
Else
MsgBox "Error: Recordset is empty"
Stop
Exit Function
End If
End Function
This is how I would do it, to get all field naems and all records as well.
Sub ADOExcelSQLServer()
' Carl SQL Server Connection
'
' FOR THIS CODE TO WORK
' In VBE you need to go Tools References and check Microsoft Active X Data Objects 2.x library
'
Dim Cn As ADODB.Connection
Dim Server_Name As String
Dim Database_Name As String
Dim User_ID As String
Dim Password As String
Dim SQLStr As String
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
Server_Name = "Your_Server_NameS" ' Enter your server name here
Database_Name = "Your_DB_Name" ' Enter your database name here
User_ID = "" ' enter your user ID here
Password = "" ' Enter your password here
SQLStr = "SELECT * FROM [Customers]" ' Enter your SQL here
Set Cn = New ADODB.Connection
Cn.Open "Driver={SQL Server};Server=" & Server_Name & ";Database=" & Database_Name & _
";Uid=" & User_ID & ";Pwd=" & Password & ";"
rs.Open SQLStr, Cn, adOpenStatic
' Dump to spreadsheet
For iCols = 0 To rs.Fields.Count - 1
Worksheets("Sheet1").Cells(1, iCols + 1).Value = rs.Fields(iCols).Name
Next
With Worksheets("sheet1").Range("a2:z500") ' Enter your sheet name and range here
'.ClearContents
.CopyFromRecordset rs
End With
' Tidy up
rs.Close
Set rs = Nothing
Cn.Close
Set Cn = Nothing
End Sub
I am writing a Excel file that can get a price form a database depending on 4 Criteria. I got to the point that it can find in one row the price (in the row there are first the 4 criteria and then the price)[See picture1]. but what i want is that every row can find the matching price. The code that i have now is this:
Option Explicit
Sub cmdSearch_Click()
Dim strCriteriaEquipment As String
Dim strCriteriaType As String
Dim strCriteriaMaterial As String
Dim strCriteriaSize As String
Dim strSQL As String
Dim strSourceTable As String
With Worksheets("Summary")
strCriteriaEquipment = .Range("B29").Value
strCriteriaType = .Range("C29").Value
strCriteriaMaterial = .Range("D29").Value
strCriteriaSize = .Range("E29").Value
End With
strSourceTable = "[DB$" & Replace(Worksheets("DB").Range("SourceData").Address, "$", "") & "]"
strSQL = "SELECT [Price] FROM " & strSourceTable & vbNewLine
strSQL = strSQL & "WHERE [Equipment]= """ & strCriteriaEquipment & """" & vbNewLine
strSQL = strSQL & "AND [Type]=""" & strCriteriaType & """" & vbNewLine
strSQL = strSQL & "AND [Material]=""" & strCriteriaMaterial & """" & vbNewLine
strSQL = strSQL & "AND [Size]=""" & strCriteriaSize & """;"
Call TableFetcher(strSQL)
strSQL = vbNullString
strCriteriaEquipment = vbNullString
strCriteriaType = vbNullString
strCriteriaMaterial = vbNullString
strCriteriaSize = vbNullString
strSourceTable = vbNullString
End Sub
Option Explicit
Public Const adOpenStatic = 3
Public Const adOpenKeySet = 1
Public Const adLockReadOnly = 1
Sub Fetcher(strSQL As String, Optional strDropDownName As String)
Dim rstRecordSet As Object 'ADODB.Recordset
Dim con As Object 'ADODB.Connection
Dim strWorkBookPath As String
strWorkBookPath = ThisWorkbook.FullName
Set con = CreateObject("ADODB.Connection")
Set rstRecordSet = CreateObject("ADODB.RecordSet")
con.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strWorkBookPath & ";" & _
"Extended Properties=""Excel 8.0;HDR=Yes"";"
rstRecordSet.Open strSQL, con, adOpenStatic, adLockReadOnly
With Worksheets("Summary")
With .DropDowns(strDropDownName)
.RemoveAllItems
.List = Split(UniqueStringWithDelimiter(rstRecordSet.GetRows, "|"), "|")
.Value = 1
End With
End With
rstRecordSet.Close
con.Close
Set rstRecordSet = Nothing
Set con = Nothing
strWorkBookPath = vbNullString
End Sub
Sub TableFetcher(strSQL As String)
Dim rstRecordSet As Object 'ADODB.Recordset
Dim con As Object 'ADODB.Connection
Dim strWorkBookPath As String
strWorkBookPath = ThisWorkbook.FullName
Set con = CreateObject("ADODB.Connection")
Set rstRecordSet = CreateObject("ADODB.RecordSet")
con.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strWorkBookPath & ";" & _
"Extended Properties=""Excel 8.0;HDR=Yes"";"
rstRecordSet.Open strSQL, con, adOpenStatic, adLockReadOnly
With Worksheets("Summary")
If Not (rstRecordSet.EOF And rstRecordSet.BOF) Then
.Range("ResultTable").Cells(5).CopyFromRecordset rstRecordSet
Else
.Range("ResultTable").Cells(5).Value = "Data Not Found!"
End If
End With
rstRecordSet.Close
con.Close
Set rstRecordSet = Nothing
Set con = Nothing
strWorkBookPath = vbNullString
End Sub
Public Function UniqueStringWithDelimiter(varArray As Variant, strDelimiter As String) As Variant
Dim varTemp() As Variant
Dim lngLoop As Long
Dim strConcat As String
ReDim Preserve varTemp(0 To 0)
varTemp(0) = varArray(0, 0)
strConcat = strConcat & varArray(0, 0)
For lngLoop = 1 To UBound(varArray, 2)
If InStr(1, strConcat, varArray(0, lngLoop), vbTextCompare) = 0 Then
strConcat = strConcat & strDelimiter & varArray(0, lngLoop)
End If
Next lngLoop
UniqueStringWithDelimiter = strConcat.
strConcat = vbNullString
Erase varTemp
End Function
How i do change the code so it does what i need it to do
What I think i'm reading is that, if four (4) criteria are met, you would then find a price. Have you used an If statement with AND modifier utilizing your four (4) criteria?
This could happen in a loop, such as:
Dim r as Long, c as Long, LR as Long
LR = Cells(Rows.Count,1).End(xlUp).Row 'Assumes column 1 is contiguous
For r = 1 to LR
c=4 'assumes you're starting with column 4
If Cells(r,c).Value="Blah" AND Cells(r,c+1).Value ="Moo" AND Cells(r,c+2).Value="Ruff" AND Cells(r,c+3).Value="Shamoo" Then
Cells(r,c+4).Copy
End If
Next r
I am having trouble when getting data from SQL Server. Here is the code.
Private Sub Form_Load()
Dim blsCritical As Boolean
'----------------------------------------------
ListBox.AddItem "Initializing..."
'----------------------------------------------
Me.Repaint
'----------------------------------------------
ListBox.AddItem "Welcome"
'----------------------------------------------
Me.Repaint
'----------------------------------------------
ListBox.AddItem "Examining your access rights..."
Call ConnectSQLServer
'----------------------------------------------
Me.Repaint
ListBox.AddItem strSQL
'----------------------------------------------
ListBox.AddItem "Opening database connection..."
'----------------------------------------------
Me.Repaint
End Sub
Sub ConnectSQLServer()
Dim cmd As ADODB.Command
Dim conn As ADODB.Connection
Dim strConn As String
Dim par As ADODB.Parameter
Set objMyConn = New ADODB.Connection
Set objMyRecordset = New ADODB.Recordset
Dim strSQL As String
objMyConn.ConnectionString = "DRIVER=SQL Server;SERVER=CHU-AS-0004;DATABASE=RTC_LaplaceD_DEV;Trusted_Connection=Yes;"
objMyConn.Open
strSQL = "SELECT [currentVersion], [standardVersion] FROM [dbo].[Version]"
If currentVersion = "" Then
MsgBox ("No currentVersion value")
ElseIf Not IsNull(currentVersion) Then
If currentVersion < standardVersion Then
MsgBox ("Upgrade is needed")
ElseIf currentVersion = standardVersion Then
MsgBox ("PASS")
Else
End If
Else
End If
Set objMyRecordset.ActiveConnection = objMyConn
objMyRecordset.Open strSQL
End Sub
I have data in SQL Server:
but I cannot get data from SQL Server. When I execute it, 'No CurrentVersion value' message pops up. I don't see any mistakes in my code. Could you help me to solve this problem?(It would be great if you can share your fixed code...)
Just whipped this up for you to show you where you went wrong... untested...
strSQL = "SELECT [currentVersion], [standardVersion] FROM [dbo].[Version]"
Set objMyRecordset.ActiveConnection = objMyConn
objMyRecordset.Open strSQL
while objMyRecordset.EOF = false
currentVersion = objMyRecordset!currentVersion
objMyRecordset.MoveNext
wend
If currentVersion = "" Then
MsgBox ("No currentVersion value")
ElseIf Not IsNull(currentVersion) Then
If currentVersion < standardVersion Then
MsgBox ("Upgrade is needed")
ElseIf currentVersion = standardVersion Then
MsgBox ("PASS")
Else
End If
Else
End If
Something like this should do the job.
Sub GetDataFromADO()
'Declare variables'
Set objMyconn = New ADODB.Connection
Set objMyCmd = New ADODB.Command
Set objMyRecordset = New ADODB.Recordset
Dim rc As Long
'Open Connection'
objMyconn.ConnectionString = "Provider=SQLOLEDB;Data Source=SAXAM\SQLEXPRESS;Initial Catalog=AdventureWorks2012; Integrated Security=SSPI;"
objMyconn.Open
'Set and Excecute SQL Command'
Set objMyCmd.ActiveConnection = objMyconn
objMyCmd.CommandText = "select * from [Person].[BusinessEntity] "
objMyCmd.CommandType = adCmdText
objMyCmd.Execute
'Open Recordset'
Set objMyRecordset.ActiveConnection = objMyconn
objMyRecordset.Open objMyCmd
'Copy Data to Excel'
'ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset)
Application.ActiveCell.CopyFromRecordset (objMyRecordset)
rc = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
ActiveSheet.Cells(rc + 1, 1).Select
'Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Value
objMyconn.Close
End Sub
Here's one more idea. Let's say you had a bunch of Select statements in a bunch of cells from A1, down to whatever, you can add sheets dynamically, and import some sample data on to each sheet, to get a sense of the data structures of multiple tables.
Assuming the following in A1:A3.
SELECT TOP 1000 * FROM [YOUR_DB].[dbo].[YOUR_TABLE1]
SELECT TOP 1000 * FROM [YOUR_DB].[dbo].[YOUR_TABLE2]
SELECT TOP 1000 * FROM [YOUR_DB].[dbo].[YOUR_TABLE3]
Run the script below.
Sub Download_From_Multiple_Tables()
'Initializes variables
Dim cnn As New ADODB.Connection
Dim rst As New ADODB.Recordset
Dim ConnectionString As String
Dim StrQuery As String
Dim rCell As Range
Dim rRng As Range
Dim sht As Worksheet
Dim LastRow As Long
Set cnn = New ADODB.Connection
'For a trusted Connection, where your user ID has permissions on the SQL Server:
cnn.Open ConnectionString:="Provider=SQLOLEDB.1;" & _
"Data Source=" & "YOUR_SERVER_NAME" & ";Initial Catalog=" & "YOUR_DB_NAME" & _
";TRUSTED_CONNECTION=YES"
'Opens connection to the database
'Timeout error in seconds for executing the entire query; this will run for 15 minutes before VBA timesout, but your database might timeout before this value
cnn.CommandTimeout = 900
Set sht = ThisWorkbook.Worksheets("Sheet1")
'Ctrl + Shift + End
LRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
Set rRng = Sheet1.Range("A1:A" & LRow)
i = 2
For Each rCell In rRng.Cells
LPosition = InStrRev(rCell.Value, "[dbo]") + 5
' Name the newly added worksheet, based on the cell value
Name = Mid(rCell.Value, LPosition + 1, 99)
' Remove [] characters, as these are not permitted in tab names
Name = Replace(Name, "[", "")
Name = Replace(Name, "]", "")
SheetName = Left(Name, 31)
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = SheetName
Worksheets(SheetName).Activate
StrQuery = rCell.Value
'Performs the actual query
rst.Open StrQuery, cnn
'Dumps all the results from the StrQuery into cell A2 of the first sheet in the active workbook
' Dump field names to the worksheet
For intFieldIndex = 0 To rst.Fields.Count - 1
ActiveSheet.Cells(1, intFieldIndex + 1).Value = rst.Fields(intFieldIndex).Name
Next intFieldIndex
' Dump the records to the worksheet
ActiveSheet.Cells(2, 1).CopyFromRecordset rst
' Sheets(i).Range("A1").CopyFromRecordset rst
i = i + 1
rst.Close
Next rCell
End Sub