Thanks Andy that helped.
Here is what I have so far.
A lot of it is commented out and its there just to show you what I have been messing around with, eg. use of parameters was an idea at first when trying to run a select statement with a where clause for every single row in the Excel table. I still have not written an approach for that.
Code:
Public Const WBOOKMASTER As String = "master.xls"
Sub InsertProducts()
Dim AccessConn As ADODB.Connection
[green]'Dim ExcelConn As ADODB.Connection[/green]
Dim rstAccessProds As ADODB.Recordset
[green]'Dim rstExcelProds As ADODB.Recordset[/green]
Dim cmdCommand As ADODB.Command
Dim AccessDB As String
[green]'Dim ExcelDB As String[/green]
Dim AccessSqlStr As String
[green]'Dim ExcelSqlStr As String[/green]
Dim r As Integer
Dim AccessBookMark As Variant
Dim sheetName As String
sheetName = "filter_products"
AccessDB = Workbooks(WBOOKMASTER).path & "\" & "master.mdb"
[green]'ExcelDB = Workbooks(WBOOKMASTER).path & "\" & "master.xls"[/green]
[green]' Open the MS Access connection[/green]
[green]'using jet provider for both of these for consistency[/green]
Set AccessConn = New ADODB.Connection
AccessConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & AccessDB & ";"
[green]'Open the MS Excel connection[/green]
[green]'Set ExcelConn = New ADODB.Connection[/green]
[green]'With ExcelConn[/green]
[green]'HDR is the header row check[/green]
[green]'.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ExcelDB & ";HDR=Yes"""""[/green]
[green]'.Open[/green]
[green]'End With[/green]
[green]'sql required for both[/green]
AccessSqlStr = "SELECT [product_code], [product_name] FROM [ProductsTest]"
[green]'ExcelSqlStr = "SELECT [product code], [product description] FROM [filter_products$]"[/green]
[green]' Set the command text for MS Access.[/green]
[green]'Set cmdCommand = New ADODB.Command[/green]
[green]'Set cmdCommand.ActiveConnection = AccessConn[/green]
[green]'With cmdCommand[/green]
[green]' .CommandText = AccessSqlStr[/green]
[green]' .CommandType = adCmdText[/green]
[green]' .Execute[/green]
[green]'End With[/green]
[green]' Open the Access recordset.[/green]
Set rstAccess = New ADODB.Recordset
[green]'Set rstAccess.ActiveConnection = AccessConn[/green]
rstAccess.Open AccessSqlStr, AccessConn, adOpenStatic, adLockReadOnly
[green]' Set the command text for MS Excel.[/green]
[green]'Set cmdCommand.ActiveConnection = ExcelConn[/green]
[green]'With cmdCommand[/green]
[green]' .CommandText = ExcelSqlStr[/green]
[green]' .CommandType = adCmdText[/green]
[green]' .Execute[/green]
[green]'End With[/green]
[green]' Open the Excel recordset.[/green]
[green]'Set rstExcel = New ADODB.Recordset[/green]
[green]'Set rstExcel.ActiveConnection = ExcelConn[/green]
[green]'rstExcel.Open cmdCommand, adOpenStatic, adLockReadOnly[/green]
Workbooks(WBOOKMASTER).Worksheets(sheetName).Activate
[green]' Find the LAST real row[/green]
lastRow = ActiveSheet.Cells.Find(What:="*", _
SearchDirection:=xlPrevious, _
SearchOrder:=xlByRows).Row
For r = lastRow To 2 Step -1
rstAccess.Filter = " product_code = '" & Trim(Range("A" & r).Value) & "'"
If rstAccess.RecordCount > 0 Then
[green]'Delete row[/green]
Workbooks(WBOOKMASTER).Worksheets(sheetName).Rows(r).Delete
End If
rstAccess.Filter = adFilterNone
Next r
[green]' Close the connections and clean up.[/green]
AccessConn.Close
[green]'ExcelConn.Close[/green]
Set cmdCommand = Nothing
Set rstAccessProds = Nothing
[green]'Set rstExcelProds = Nothing[/green]
Set AccessConn = Nothing
[green]'Set ExcelConn = Nothing[/green]
[green]' Get parameter value and append parameter.[/green]
[green]'prodCode = Trim(Cell.Value)[/green]
[green]'Set prmProdCode = cmdCommand.CreateParameter("prodcode", adVarChar, adParamInput)[/green]
[green]'cmdCommand.Parameters.Append prmByRoyalty[/green]
[green]'cmdCommand.Value = prodCode[/green]
End Sub
It seems to work ok.
I initially tried to get it to work by connecting to the Excel workbook but the ThisWorkbook is the one I need to connect to so I got this runtime error: -2147467259 (80004005)
And then checked the below and decided not to try that approach for now:
"When you retrieve a Microsoft ActiveX Data Objects (ADO) Recordset from an Excel worksheet that is open in Excel, a memory leak occurs in the Excel process. Repeated queries may eventually cause Excel to run out of memory and raise an error, or cause Excel to stop responding."
I have decided not to bother verifying whether the "product name" matches what is found for the code, because hopefully the codes should be correct. If I was to check the name I would need to replace some of the name such as O'Brian to O''Brian, I believe but I am unsure on what else to check for and how best to do it??
Here is a list of things that I would like to try and change with this:
1. Create a recordset or collection of the values in the Excel sheet so that any that are found in the Access table and can be deleted from there. Then the Excel collection/recordset can be used to update the Access table directly with the ones that are missing.
As you can see I have been playing around with using a command object but then I noticed this "a Command object is required when you want to persist the command text and re-execute it, or use query parameters. " and thought, I probably won't need it.
I also had a play around with bookmarking the filtered record in the recordset but that didnt seem applicable for what I was attempting.
If anyone has some feedback or an approach for adding the Excel values to a collection for updating the Access table that would be a great help.
Thanks