Adding a Delimiter to a memo field in Access - vba

I am trying to delimit a memo field. The field has within it multiple notes that I need to parse out into different columns. Each note however follows the same logic, starts with mm/dd/yyyy then the note itself followed by a space.
So an example for one memo field would be
01/25/2000 worked on Rack-ID 03/03/2010 contracted Rack-ID 05/15/2014 updated Rack-ID
I need each note parsed out into a different column in Access.
I was working on the Split function in VBA, they had originally had "|" as a delimiter but removed it, now I have to pull on the dates
Note "tbl_example" is the table in my test access database
"Tx_example" is the name of the column holding the data to be delimited in my test access database
Sub Example()
On Error GoTo err_Handler
Dim rsD As DAO.Recordset
Set rsD = CurrentDb.OpenRecordset("tbl_Example")
Do While Not rsD.EOF
rsD.Edit
rsD!F1 = Trim(Split(rsD!Tx_Example, "|")(0))
rsD!F2 = Trim(Split(rsD!Tx_Example, "|")(1))
rsD!F3 = Trim(Split(rsD!Tx_Example, "|")(2))
rsD.Update
rsD.MoveNext
Loop
sub_Exit:
rsD.Close
Set rsD = Nothing
Exit Sub
err_Handler:
If Err.Number = 9 Then
Resume Next
Else
MsgBox "Err: " & Err.Number & vbNewLine & Err.Description
End If
End Sub
Not certain how I replace the "|" with a date search.
Also I'm not against doing a replace and inserting "|" right before each date so I would have my delimiter back.
Problem is I'm not sure how to find the date in a text memo field, otherwise I would be able to use the replace function, or an update query.
Any help is appreciated, thanks.

Public Function AddPipesBeforeDates(ByVal strText As String) As String
Dim regex As RegExp
Dim matches As Object
Set regex = CreateObject("VBScript.RegExp")
regex.Global = True
regex.Pattern = "\d{2}/\d{2}/\d{4}"
Set matches = regex.Execute(strText)
For Each m In matches
strText = Replace(strText, m, "|" & m)
Next
AddPipesBeforeDates = strText
Set matches = Nothing
Set regex = Nothing
End Function
Sub Example()
On Error GoTo err_Handler
Dim rsD As DAO.Recordset
Dim results as variant
Set rsD = CurrentDb.OpenRecordset("tbl_Example")
Do While Not rsD.EOF
results = split(AddPipesBeforeDates(rsD!Tx_Example), "|")
rsD.Edit
rsD!F1 = Trim(results(1))
rsD!F2 = Trim(results(2))
rsD!F3 = Trim(results(3))
rsD.Update
rsD.MoveNext
Loop
sub_Exit:
rsD.Close
Set rsD = Nothing
Exit Sub
err_Handler:
If Err.Number = 9 Then
Resume Next
Else
MsgBox "Err: " & Err.Number & vbNewLine & Err.Description
End If
End Sub

I wrote something like this recently to pull dated notes out of a memo field. This code may not work exactly as is, but will get you closer and give you some ideas.
Some initial notes: Don't expect the routine to do the full job on the first sweep. Create a temp table to write your results to, and each time you run the routine, clear the temp table first. After each run, tweak your code to catch everything it missed in the previous run. This way, you will refine the routine until you capture all your data accurately. You may also have to hand edit some notes to get them to work
+----------+------------+
| Field | DataType |
+----------+------------+
| NoteId | AutoNumber |
| ParentId | Long |
| NoteDate | Date/Time |
| NoteNext | Memo |
+----------+------------+
Also, I highly recommend not using multiple note fields in the same table. Your Notes table should look like my temp_Notes table above. After your routine is successful, its a simple matter of running against your Notes table rather than temp_Notes.
Public Sub MigrateNotes()
Dim db As DAO.Database
Dim rsDest As DAO.Recordset
Dim rsSource As DAO.Recordset
Dim nId As Long
Dim aNotes() As String
Dim n As Long
Dim dtDate As Date
Dim sNote As String
On Error GoTo EH
DoCmd.Hourglass True
Set db = CurrentDb
db.Execute "DELETE * FROM temp_Notes"
Set rsDest = db.OpenRecordset("SELECT * FROM temp_Notes")
Set rsSource = db.OpenRecordset("SELECT RowId,Diary FROM SourceNotes")
With rsSource
Do Until .EOF
nId = .Fields("RowId").Value
aNotes = parseNotes(.Fields("Diary").Value)
For n = 0 To UBound(aNotes)
dtDate = CDate(Left(aNotes(n), 10))
sNote = Right(aNotes(n), Len(aNotes(n)) - 11)
With rsDest
.AddNew
.Fields("RowId").Value = nId
.Fields("NoteDate").Value = dtDate
.Fields("NoteText").Value = sNote
.Update
End With
Next 'n
.MoveNext
Loop
End With
MsgBox "Complete"
GoTo FINISH
EH:
With Err
MsgBox .Number & vbCrLf & .Source & vbCrLf & .Description
.Clear
End With
'for debugging purposes
Debug.Assert 0
GoTo FINISH
Resume
FINISH:
DoCmd.Hourglass False
On Error Resume Next
'release resources
If Not rsDest Is Nothing Then
rsDest.Close
Set rsDest = Nothing
End If
If Not rsSource Is Nothing Then
rsSource.Close
Set rsSource = Nothing
End If
End Sub
Private Function parseNotes(ByVal sRaw As String) As String()
Dim nYear As Long
Dim sYearToken As String
Dim nIndex As Long
Dim nSkip As Long
For nYear = 1999 To Year(Date)
sYearToken = "/" & nYear & " "
'use 12 to skip past first date ("mm/dd/yyyy " = 11)
nSkip = 12
Do
'find the end of the date
nIndex = InStr(nSkip, sRaw, sYearToken)
If nIndex > 0 Then
'find the start of the date
nIndex = nIndex - 6
sRaw = Left(sRaw, nIndex) & vbCrLf & Right(sRaw, Len(sRaw) - nIndex)
'use 12 to skip past next date
nSkip = nIndex + 12
End If
Loop Until nIndex <= 0
Next 'n
parseNotes = Split(sRaw, vbCrLf)
End Function

Related

Why does this line of code work half the time, and the other half gives me Data Type Conversion Error 3421

Here is the full code:
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim frm As Access.Form
Dim i As Long
'For readability
Set frm = Forms!Frm_JobTicket
'Open Tbl_Schedule for adding Schedule Dates
Set db = CurrentDb
Set rs = db.OpenRecordset("Tbl_Schedule", dbOpenDynaset, dbAppendOnly)
'Creates loop for fields 1-14. Sets Date_ScheduledX = Forms!Frm_JobTicket!Txt_DateScheduledX. Runs through Loop then closes recordset
rs.AddNew
For i = 1 To 14
If (Not IsNull(frm("Txt_DateScheduled" & i & "_JobTicket"))) Then
rs("Date_Scheduled" & i) = frm("Txt_DateScheduled" & i & "_JobTicket")
End If
Next i
'Adds in Sales Order Number to Tbl_Schedule
rs!Sales_Order_Number = frm("Sales_Order_Number")
'Adds in Part Number to Tbl_Schedule
rs!Part_Number = frm("Part_Number")
'Adds updates and closes table
rs.Update
rs.Close
'Shows message box to inform the User if item was Scheduled
MsgBox "Item Scheduled."
'Runs Private Sub above. Clears all values from DateScheduled1-14 on Frm_JobTicket to null
ClearFields
'Clears DB and RS to null
Set db = Nothing
Set rs = Nothing
The line that doesn't work is this rs("Date_Scheduled" & i) = frm("Txt_DateScheduled" & i & "_JobTicket"). Sometimes it will run perfectly fine, and other times it gives me an endless flow of 3421 Data type conversion errors. I do not know what could be going wrong, none of the fields have default values, all of the fields in the table side are Date/Time with this same format, and now I am checking for nulls.
Any help would be greatly appreciated!!
Maybe something like
If Len(Me.Txt_DateScheduled & vbNullString) > 0 Then
rs("Date_Scheduled" & i) = frm("Txt_DateScheduled" & i & "_JobTicket")
Else
rs("Date_Scheduled" & i) = ""
End If
This is completely untested, but I think you should get the concept.

How get Cells's value and check before open excel file use VBA in outlook

I tried to search value of cell from outlook script and check whether Does it exist in excel file, if yes, open excel file, else do nothing. I can open file and search where is that value in range. But my problem is I don't know how to search that value in range and get it's position without open excel file.
EDIT 1:
Here is my detail issue: EX:
I have a phone number at column "Phone Number". I would like to find where Column of "Phone Number" (because sometime it will change to another column). After I find position of column, I would like to search whether number "123876" is existed in that column (until this time excel file still close). Now, if number "123876" is existed, open that excel file, else do nothing.
Here is my code to search if file open
Sub test()
Dim objExcel As Object
Dim WB As Object
Dim WS As Object
'Open excel file
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
Set WB = objExcel.Workbooks.Open("D:\Book1.xlsm")
WB.Activate
Set WS = WB.Worksheets("Sheet1")
'Search position of column "Phone Number"
Phone_Number_Col = Chr(WS.Range("A:Z").Find("Phone Number", LookIn:=xlValues).Column + 64) 'It will return 5 and change to "E" for this column
'Search whether does my number is exist in this file
Dim range_1 As Range
Set Found_Nprod = WS.Range(Phone_Number_Col & ":" & Phone_Number_Col).Find("123876", LookIn:=xlValues)
If Not Found_Nprod Is Nothing Then 'found my number
MsgBox ("This value is existed")
Else ' not find my number
MsgBox ("This value is not existed in this file")
End If
End Sub
Above code just can find when excel file is opened. But my problem is how to find like that without open file, It just open file when that file have my number "123876"
EDIT 2:
I found a peace of code which can get value of cell without open. It's run ok But I don't know how to use find function with it.
This is my function I found
Sub ReadClosed()
'
' Credit this To Bob Umlas
'
Dim strPath As String
Dim strFile As String
Dim strInfoCell As String
strPath = "D:\"
strFile = "Book1.xlsm"
i = 3
strInfoCell = "'" & strPath & "[" & strFile & "]Sheet1'!R" & i & "C1"
MsgBox "In Cell A1 = " & ExecuteExcel4Macro(strInfoCell), vbInformation, strFile
Ok, this is how I can help you with - this is a code, that I am using, and it gives you the row of the wanted string, if you give it in which column to search. If it is not the wanted string, it returns -1. If you want the second repetitable of the string, you should give in the optional parameter l_more_values_found a value of 2. If your string is Phone and in the sheet it is Phones, you should set look_for_part as True. Prety much this is how it works. Lets imagine you have this:
If you run the MyTest Sub, you would get 4 as a result. 4 is the phone number 155, which is given as a parameter to l_locate_value_row. In your case, you can check once you know the column that it has to search, whether it returns -1.
Here comes the code:
Public Function l_locate_value_row(target As String, ByRef target_sheet As Worksheet, _
Optional l_col As Long = 2, _
Optional l_more_values_found As Long = 1, _
Optional b_look_for_part = False) As Long
Dim l_values_found As Long
Dim r_local_range As Range
Dim my_cell As Range
l_values_found = l_more_values_found
Set r_local_range = Nothing
target_sheet.Activate
Set r_local_range = target_sheet.Range(target_sheet.Cells(1, l_col), target_sheet.Cells(Rows.Count, l_col))
For Each my_cell In r_local_range
'The b_look_for_part is for the vertriebscase
If b_look_for_part Then
If target = Left(my_cell, Len(target)) Then
If l_values_found = 1 Then
l_locate_value_row = my_cell.Row
Exit Function
Else
l_values_found = l_values_found - 1
End If
End If
Else
If target = Trim(my_cell) Then
If l_values_found = 1 Then
l_locate_value_row = my_cell.Row
Exit Function
Else
l_values_found = l_values_found - 1
End If
End If
End If
Next my_cell
l_locate_value_row = -1
End Function
Public Sub MyTest()
Dim l_col As Long
l_col = l_locate_value_row("155", ActiveSheet, 3, 1, False)
Debug.Print l_col
End Sub
An ADODB Query is ideal for retrieving data from a closed workbook.
Phone Numbers
Test
Code
Function hasPhoneNumber(FilePath As String, PhoneNumber As Variant) As Boolean
Const adOpenStatic = 3, adLockOptimistic = 3, adCmdText = 1
Dim conn As Object, rs As Object
Set conn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & FilePath & _
";Extended Properties=Excel 12.0;"
rs.Open "SELECT (Count([Phone Number]) > 0) AS hasPhoneNumber FROM [Sheet1$]" & _
" WHERE Cstr([Phone Number])='" & PhoneNumber & "';", conn, adOpenStatic, adLockOptimistic, adCmdText
hasPhoneNumber = CBool(rs!hasPhoneNumber)
On Error Resume Next
rs.Close
Set rs = Nothing
conn.Close
Set conn = Nothing
End Function

Access database import from excel file fails when AssocID (first field) is mixed with integers and strings

I have an access database with vba code that is attempting to access an excel sheet and copy the data to a recordset using DAO.recordset. If all of the column (assocId) is integer the import works wonderfully if all are strings it works but if you have a mixed back (eg 111111 | Vinny | etc and then on row two you have JOE-1 | Joe | etc) the import will fail. It says "You cannot record your changes because a value you entered violates the settings defined for this table"
Here is the offending sub:
Public Sub LoadFileInfo()
'Load information from selected file
On Error GoTo ErrorHappened
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim i As Integer
Dim lastTransType As String
Dim transactionCounter As Integer
Dim currentRecord As CurrentImportRecord
Dim wtf As Variant
Set db = CurrentDb()
Set rs = db.OpenRecordset(selectTransTypesSql & GetSetting("PayrollManualImportExportTransactionTypes") & ")")
ReDim transTypes(DCount("TransType", "MasterTransactionTypes", "IsActive <> 0")) As MasterTransactionTypes
rs.MoveFirst
Do While Not rs.EOF
'Add each transaction type and desc to the Private Type and increment the appropriate counter
GetMasterTransactionTypes rs!TransType, rs!TransDesc, i
rs.MoveNext
i = i + 1
Loop
rs.Close
Set db = OpenDatabase(importFileName, False, True, "Excel 12.0;HDR=Yes")
Set rs = db.OpenRecordset("SELECT * FROM " & "[" & GetSheetName(importFileName) & "$]" & " ORDER BY TransType")
rs.MoveLast
importFields = vbNullString
For i = 0 To rs.Fields.count - 1
importFields = importFields & rs.Fields(i).Name & ","
Next
fullImport = (rs.Fields.count > 4)
i = 0
transactionCounter = 1
lblFile.Caption = "File name: " & importFileName
Dim rowNum As Variant
rowNum = rs.RecordCount
wtf = rs.GetRows(rowNum)
ReDim ledgerEntries(rs.RecordCount) As PayrollLedgerImport
'Check to see if the recordset actually contains rows; if so push transaction objects to private type array
rs.MoveFirst
Do While Not rs.EOF
currentRecord.associateId = CStr(rs!assocId)
currentRecord.transactionType = rs!TransType
currentRecord.transactionNotes = CStr(rs!TransNotes)
If lastTransType = CStr(currentRecord.transactionType) Then
transactionCounter = transactionCounter + 1
Else
transactionCounter = 1
End If
If IsValidTransType(currentRecord.transactionType) Then
If Not fullImport Then
currentRecord.transactionAmount = rs!TransAmount
GetPayrollTransactions currentRecord.associateId, currentRecord.transactionType, currentRecord.transactionAmount, currentRecord.transactionNotes, i, transactionCounter
Else
currentRecord.transactionAmount = rs!TransAmt
GetPayrollTransactions currentRecord.associateId, currentRecord.transactionType, currentRecord.transactionAmount, currentRecord.transactionNotes, i, transactionCounter
End If
Else
MsgBox (currentRecord.transactionType & ": Not A Valid Transaction Type")
End If
lastTransType = rs!TransType
rs.MoveNext
i = i + 1
Loop
FormatFileInformationWindow
cmdImportFile.Enabled = True
End Sub
I've been at this for hours. I've tried casting all the columns when I take them in and I get the same issue. Works fine for all ints or all strings but in reality some of our employees have string and some have int for employee ID. I tried taking them all in as string converting where necessary but that didn't work either. Only thing that works is two sheets - one containing strings one containing ints.

VBA Access: Import CSV with additonal header data

I am new to coding VBA. Was wondering if you all could help me? I have a CSV file which is structured as the following:
- First 22 rows cover the specfic header data(this all loads in one column in excel)
- column headers for table are in Row 23
- the data is actually located from row 24 onward.
What the code needs to do is insert this data in new table with the right column titles. Also while inserting it needs to input the file name and header data in the first few columns of the table.
So far I have imported the entire CSV into an array I believe:
See what I have so far:
Sub readCSV()
Dim fs As Object
Dim fso As New FileSystemObject
Dim tsIn As Object
Dim sFileIn, filename As String
Dim aryFile, aryHeader, aryBody As Variant
sFileIn = "C:\doc\test.csv"
Set filename = fso.GetFileName(sFileIn)
Set fs = CreateObject("Scripting.FileSystemObject")
Set tsIn = fs.OpenTextFile(sFileIn, 1)
sTmp = tsIn.ReadAll
aryFile = Split(sTmp, vbCrLf)
For i = 1 To 22
aryHeader(1, i) = aryFile(i)
Next i
For i = 23 To UBound(aryFile)
aryBody(i) = Split(aryFile(i), ",")
DoCmd.RunSQL "INSERT INTO MAINS VALUES (filename,aryHeader(1),aryBody(i))"
Next i
End Sub
is this correct? Can anyone see of i am taking the right approach
UPDATE - recoded this a bit
Use DoCmd.TransferText instead of rolling out your own code:
http://msdn.microsoft.com/en-us/library/office/ff835958%28v=office.15%29.aspx
In your Import Specification, you can set the starting row.
See Skip first three lines of CSV file (using DoCmd?) in MS Access for more information!
Edit: The import specification can be changed to rename the fields etc. See http://www.access-programmers.com/creating-an-import-specification-in-access-2003.aspx (the Import wizard exists in Access 2007 as well) and the Advanced dialog specifically.
I was a bit irked by the use of multiple arrays in your code (which is super confusing, to me, anyway, because you are looking at counters everywhere) so I thought I would post an alternative for you. If you can do it your way, more power to you, but if you run into problems, you can try this. Code below is much more verbose, but may save you time in the future if you hand it off or even have to come back to it yourself and have no idea what is going on (lol):
Sub ReadCSV()
On Error GoTo ErrorHandler
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim fso As Scripting.FileSystemObject
Dim tst As Scripting.TextStream
Dim strFileName As String
Dim intCurrentLine As Integer
Dim strCurrentLine As String
Dim intHeaderRows As Integer
Dim strHeader As String
Dim strHeaderDelimInField As String
'Consider these your 'constants', so you don't come back to this code in a month
'and wonder what the random numbers mean.
intHeaderRows = 22 'Number of header rows in CSV.
strHeaderDelimInField = "~" 'The character(s) you want to separate each
'header line, in field.
strFileName = "C:\IrregularCSV.csv"
intCurrentLine = 1 'Keep track of which line in the file we are currently on.
'Next two lines get a reference to your table; will add data via DAO and not SQL,
'to avoid messy dynamic SQL.
Set db = CurrentDb()
Set rst = db.OpenRecordset("Mains", dbOpenDynaset)
Set fso = New Scripting.FileSystemObject
Set tst = fso.OpenTextFile(strFileName, ForReading)
'Instead of storing data in arrays, let's go through the file line by line
'and do the work we need to do.
With tst
Do Until .AtEndOfStream
strCurrentLine = .ReadLine
If intCurrentLine <= intHeaderRows Then
strHeader = strHeader & strHeaderDelimInField & strCurrentLine
Else
'Add the records via DAO here.
rst.AddNew
'In DAO, rst.Fields("FieldName") are the columns in your table.
rst.Fields("FileName") = strFileName
'Remove leading delimiter with Right.
rst.Fields("HeaderInfo") = Right(strHeader, Len(strHeader) - 1)
'Note that Split always returns a zero-based array
'and is unaffected by the Option Base statement.
'The way below is less efficient than storing
'the return of Split, but also less confusing, imo.
rst.Fields("Field1") = Split(strCurrentLine, ",")(0)
rst.Fields("Field2") = Split(strCurrentLine, ",")(1)
rst.Fields("Field3") = Split(strCurrentLine, ",")(2)
rst.Update
End If
intCurrentLine = intCurrentLine + 1
Loop
End With
tst.Close
rst.Close
ExitMe:
Set tst = Nothing
Set fso = Nothing
Set rst = Nothing
Set db = Nothing
Exit Sub
ErrorHandler:
Debug.Print Err.Number & ": " & Err.Description
GoTo ExitMe
End Sub
To be honest, I think there are a lot of gotchas to the way you are going about it. Not saying it won't work, because I think it can, but this method is more robust. An unexpected single quote won't ruin your work and using a data object to do the inserts is not prone (well, less, at least) to SQL injection issues. And I've done it with no persisted arrays. Anyway, some food for thought. Good luck.
this is what i ended up:
Sub ReadCSV2()
Dim fs As Object
Dim filename As String
Dim tsIn As Object
Dim sFileIn As String
Dim aryHeader, aryBody As Variant
Dim Text As String
Dim sqlcre As String
Dim sqlsta As String
sFileIn = "C:\test\test.csv"
filename = GetFilenameFromPath(sFileIn) 'function to get the file name
Set fs = CreateObject("Scripting.FileSystemObject")
Set tsIn = fs.OpenTextFile(sFileIn, 1)
For i = 1 To 23
Tmps = tsIn.ReadLine
Next i
aryHeader = Split(Tmps, ",")
On Error Resume Next
DoCmd.RunSQL "DROP TABLE tempdata"
On Error GoTo 0
sqlcre = "CREATE TABLE tempdata ([Filename] Text,"
For k = LBound(aryHeader) To UBound(aryHeader)
sqlcre = sqlcre & "[" & aryHeader(k) & " " & k + 1 & "] Text,"
Next k
k = k - 1
sqlcre = Left(sqlcre, Len(sqlcre) - 13) & ")"
'Debug.Print k
'Debug.Print sqlcre
DoCmd.RunSQL sqlcre
DoCmd.SetWarnings False
While Not tsIn.AtEndOfStream
Tmps = tsIn.ReadLine
aryBody = Split(Tmps, ",")
sqlsta = "INSERT INTO tempdata VALUES ('" & filename & "','"
For M = LBound(aryBody) To UBound(aryBody)
sqlsta = sqlsta & Replace(aryBody(M), "'", "`") & "', '"
Next M
M = M - 1
Debug.Print M
If M < k Then
Text = ""
For i = 1 To (k - M)
Text = Text & "', '"
Next i
sqlsta = sqlsta & Text
End If
sqlsta = Left(sqlsta, Len(sqlsta) - 7) & ")"
'Debug.Print sqlsta
'Debug.Print k
DoCmd.RunSQL sqlsta
Wend
DoCmd.SetWarnings True
End Sub

Populate result of another query into combo box

I have an Excel file for colleagues to extract reports from SQL server.
We created separate user and password for their department.
I have the module which shows the result of SQL query in an Excel file.
Here is working code:
Sub Button3_Click()
ActiveSheet.Cells.Clear
Dim qt As QueryTable
sqlstring1 = "SELECT * FROM dbo.ReportDataAdded ORDER BY ProductID, CountryCodeID"
With ActiveSheet.QueryTables.Add(Connection:=getConnectionStr2, Destination:=Range("A3"), Sql:=sqlstring1)
.Refresh
End With
End Sub
Private Function getConnectionStr2()
getConnectionStr2 = "ODBC;DRIVER={SQL Server};" & _
"DATABASE=em_CountryConsumer;" & _
"SERVER=192.192.192.192;" & _
"UID=UserName;" & _
"PWD=passwordd;"
End Function
I need to populate the result of another query into combo box. For that I need to get result of query into variable with dataset datatype.
How can I change my VBA code to do that?
Here is an example of how I have handled a similar problem in the past:
First here is a function to Query the database based with a given connection_string and query.
Function GetQuery(SQL As String, connect_string As String, Optional HasFields As Long = 0) As Variant
'''
' Returns: A Variant() Array with results from query.
'
' HasFields is an optional field to include the field names in the array
' Any integer in this field will include fields, leave it blank for just data
'''
Dim Conn As New ADODB.Connection
Dim RS As New ADODB.Recordset
Dim data_sheet As Worksheet
Dim R As Long, C As Long
Dim dbArr() As Variant
'''''''''''''''''''''''''''''
' Setting Up DB connection
'''''''''''''''''''''''''''''
conReTry:
On Error GoTo ConnectErr:
With Conn
.ConnectionString = connect_string
.Open
End With
ConnectErr:
If Err.Number <> 0 Then
MsgBox "There was an issue connecting to the Central DB."
Resume subexit
End If
On Error GoTo 0
''''''''''''''''''''''
' Starting the connection to DB
''''''''''''''''''''''
On Error GoTo QueryErr:
RS.Open SQL, Conn, adOpenStatic
QueryErr:
If Err.Number <> 0 Then
MsgBox "There was a problem with the Query. Could not get results from the statement:" & vbCrLf & Err.Description
dbArr = Array(" Failed Q ", " Failed Q ")
Resume subexit
End If
On Error GoTo 0
'''''''''''''''''''''
' Parse Data and fill array: DBarr
'''''''''''''''''''''
R = 0
#If VBA7 Then
Dim tmp_rowNum As LongPtr, tmp_colNum As LongPtr
Dim rowNum As Integer, colNum As Integer
tmp_rowNum = RS.RecordCount
tmp_colNum = RS.Fields.Count
rowNum = CLng(tmp_rowNum)
colNum = CLng(tmp_colNum)
#Else
Dim rowNum As Long, colNum As Long
rowNum = RS.RecordCount
colNum = RS.Fields.Count
#End If
If HasFields = 0 Then
ReDim dbArr(1 To rowNum + 1, 1 To colNum)
Else
ReDim dbArr(1 To rowNum + 2, 1 To colNum)
End If
Do While Not RS.EOF
R = R + 1
For C = 1 To RS.Fields.Count
If R = 1 And HasFields = 1 Then
dbArr(R, C) = RS.Fields(C - 1).Name
ElseIf Not R = 1 Then
dbArr(R, C) = RS.Fields(C - 1).Value
End If
Next
If Not R = 1 Then RS.MoveNext
Loop
subexit:
GetQuery = dbArr
Set Conn = Nothing
Set RS = Nothing
End Function
Next use the result of the Query (A [multi-dimensional] Array) to set the range in a worksheet:
Sub SetInitData()
Application.ScreenUpdating = False
Application.EnableEvents = False
Dim sql_string As String, connect_String as String
Dim ws as Worksheet
Set ws = ThisWorkbook.Sheets(config.DATA_SHEET_NAME)
sql_string = config.GET_INITIAL_PACKTYPE_QUERY
connect_string = config.MAIN_CONNECTION_STRING
Debug.Print sql_string
Dim packtypedata As Variant
packtypedata = GetQuery(sql_string)
ws.Range(ws.Cells(1, 1), ws.Cells(UBound(packtypedata), UBound(packtypedata, 2))).Value = packtypedata
'' Keep Total Rows for next routine explained below
Dim total_rows as Integer
total_rows = UBound(packtypedata)
SetComboBoxValues(total_rows)
''' Turn on events and screen updating again
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Finally you want to set the ComboBox:
Sub SetComboBoxValues(total_rows As Integer)
Dim ws as Worksheet, data_ws as Worksheet
Dim data_arr as Variant
Dim pack_dd as DropDown
Set ws = ThisWorkbook.Sheets(config.INPUT_SHEET_NAME)
Set data_ws = ThisWorkbook.Sheets(config.DATA_SHEET_NAME)
data_arr = data_ws.Range(data_ws.Cells(1,config.DATA_COL_DROPDOWN_INDEX),
data_ws.Cells(total_rows,config.DATA_COL_DROPDOWN_INDEX)).Value
Set pack_dd = ws.Shapes(config.MAIN_DATA_DROPDOWN_NAME).OLEFormat.Object
pack_dd.List = pack_dd
''' To set the index
pack_dd.ListIndex = 1
End Sub
** Note -- The GetQuery function has some kinks that I haven't had time to work out, namely I don't think the HasFields option to include headers actually works.
Also I'm using DropDowns, so I'm not sure if you are using the same type of object.
Good Luck