I am running some VBA code against an MS Access 2010 DB that is linked to a Sharepoint list. The code loops thru record sets and updates a specific column given some conditions.
While running this against the DB when it is a copy/not-linked to the live sharepoint list, when I step thru using debug I can see the DB fields get updated without needing to complete the program or exit debug. However when running in linked mode I can't see the updates to the row/column when stepping thru with debug.
Is this expected behavior? Is there anyway to force and see the updates? I would just like to be certain this behaves correctly before running 1k+ updates. Below is a sample of basically what I'm doing. Basically even when I've stepped to the next rst, I can't see the updates to "Notes Field" in the MS Access Table for the previous rst records.
Sub ListAttachments()
Dim dbs As DAO.Database
Dim rst As DAO.Recordset2
Dim rsA As DAO.Recordset2
Dim fld As DAO.Field2
'Get the database, recordset, and attachment field
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("tblAttachments")
Set fld = rst("Attachments")
'Navigate through the table
Do While Not rst.EOF
'Get the recordset for the Attachments field
Set rsA = fld.Value
'Print all attachments in the field
Do While Not rsA.EOF
Debug.Print , rsA("FileType"), rsA("FileName")
rst.Edit
' Just and example I'm not actually put text below in
rst("Notes Field") = "This record has one or more attachments"
rst.Update
'Next attachment
rsA.MoveNext
Loop
rsA.Close
'Next record
rst.MoveNext
Loop
rst.Close
dbs.Close
Set fld = Nothing
Set rsA = Nothing
Set rst = Nothing
Set dbs = Nothing
End Sub
Any help is appreciated! Thanks in advance.
Related
I have developed an Access Database query which references an object on a form in order to dynamically filter the data. The criteria upon which the query is filtered is as follows:
[Forms]![frmMain]![NavigationSubform].[Form]![Frame64]
Where [frame64] is where the user chooses one of two options on a form.
Whilst this query runs fine in Access, I want to use this query in a piece of VBA code, but the problem is, when I try to open the record set, VBA won't allow me.
Dim db As Database
Dim rs As Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("qryMergeEzineCompleteMerges", dbOpenDynamic, dbSeeChanges)
Through my research, I have discovered that it is because VBA doesn't recognise the query criteria I have defined as it refers to a form.
Can anyone please show me how I can reference this recordset in VBA so that it filters by the criteria I have stipulated in the query itself?
Many thanks
You need to open the Recordset through a QueryDef.
Sub Whatever()
Dim db As Database
Dim qdf As QueryDef
Dim rs As Recordset
Set db = CurrentDb()
Set qdf = db.QueryDefs("qryMergeEzineCompleteMerges")
'add any parameters here
With qdf
.Parameters("[parameter1]").Value = value1
.Parameters("[parameter2]").Value = value2
End With
Set rs = qdf.OpenRecordset(dbOpenDynaset)
'...
rs.Close
Set rs = Nothing
qdf.Close
Set qdf = Nothing
Set db = Nothing
End Sub
This may sound pretty stupid but the easiest way to solve this is to create two constants for the dbOpenDynamic and dbSeeChanges values and set their values to the right integer values. You can of course also just type the relevant integer values in the OpenRecordset call.
I have a macro (created with the macro wizard) which runs a number of queries and then outputs a table to excel. The table has more then the 65,000 records limit for exporting formatted tables. How can I export the table without formatting in the macro? Here is the error I receive after I run the macro.
I know you are using access vba to export the records but have you thought about using a datalink to your query from excel and using the access vba to open the excel file and refresh the data table? this will definitely eliminate any issues with max rows and should not have any failure issues due to export size. If you need more info on how to do that let me know and I'll add more info here.
Here is the code requested by Anthony Griggs above. But it is a VBA solution, not a macro solution, so not directly responsive to the question as posted. This was how I worked around the problem and have had this successfully in production for a long time.
Be sure to add the reference to "Microsoft ActiveX Data Objects 2.8 Library" (or current version for you) and also the "Microsoft Excel 12.0 Object Library" (or current version for you) before using this code. The save changes and quit at the end are critical, otherwise it leaves Excel open in the background that you have to kill via task manager.
Dim rs As New ADODB.Recordset
Dim xl As New Excel.Application
Dim xlWb As Excel.Workbook
Dim xlRange As Excel.Range
xl.Visible = False
xl.ScreenUpdating = False
vcurfilename = "MyFilename.XLSX”
Set xlWb = xl.Workbooks.Open(vcurfilename, 0, False, 5, "password", "password")
rs.Open "Select * from qryMyAccessQuery", CurrentProject.Connection, adOpenForwardOnly, adLockReadOnly
Set xlRange = xlWb.Worksheets("MyExcelSheetName").Range("A1").Offset(1, 0)
xlWb.Sheets("MyExcelSheetName ").Range("a2:bq25000").ClearContents
xlRange.Cells.CopyFromRecordset rs
xl.Range("Table1").Sort key1:=xl.Range("Table1[[#All],[MyColumnName]]"), _
order1:=xlAscending, Header:=xlYes
On Error Resume Next
xl.Range("table1").Columns("A").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
On Error GoTo 0
rs.Close
xl.Range("table1").ListObject.HeaderRowRange.Find("MyColumnName1").EntireColumn.NumberFormat = "dd-MMM-yy"
xl.Range("table1").ListObject.HeaderRowRange.Find("MyColumnName2").EntireColumn.NumberFormat = "dd-MMM-yy"
xl.Range("table1").ListObject.HeaderRowRange.Find("MyColumnName3").EntireColumn.NumberFormat = "dd-MMM-yy"
xlWb.Close SaveChanges:=True
xl.Quit
DoEvents
So I'm converting an access back-end to SQL. I've tried a few different tools (SSMA, Upsizing Wizard, and a simple import). I've found so far that the SSMA tool and importing seem to work the best, eliminating most of the work necessary for me. However, I'm running into one issue I can't figure out how to overcome.
Two fields allow multiple values (dropdown with check boxes). In converting these, it errors in a way that it not only doesn't carry all of the information over, but also grabs information from another field (and doesn't carry that information over).
I've tried forcing access to only accept the first value (and get rid of multi-values all together), but it won't let me.
Any ideas?
This should get you started. It will turn all those values which are selected in the multi select field into their own table. You will need to establish the relationships between the three tables to create a true many to many relationship after the fact.
Sub ExtractMultiValueFields()
Dim JoinTable As New DAO.TableDef
JoinTable.Name = "JoinTable"
With JoinTable
.Fields.Append .CreateField("MainTableId", dbInteger)
.Fields.Append .CreateField("JoinToValue", dbText)
End With
Dim joinRs As DAO.Recordset
CurrentDb.TableDefs.Append JoinTable
Set joinRs = CurrentDb.OpenRecordset("JoinTable")
Dim rs As DAO.Recordset
Dim childrs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset("select * from table1")
Do While Not rs.EOF
Debug.Print rs("ID")
Set childrs = rs("col1").Value
Do While Not childrs.EOF
Debug.Print childrs("value") 'always "value"
joinRs.AddNew
joinRs("MainTableId") = rs("ID")
joinRs("JoinToValue") = childrs("value")
joinRs.Update
childrs.MoveNext
Loop
rs.MoveNext
Loop
End Sub
I"m opening a record set like so:
Dim rst As DAO.Recordset
Set rst = db.OpenRecordset(curSKU)
Can you open up the same recordset twice with different variables:
Dim rst As DAO.Recordset
Set rst = db.OpenRecordset(curSKU)
Dim rst2 As DAO.Recordset
Set rst2 = db.OpenRecordset(curSKU)
Is this allowed? Will it cause problems if I try to iterate through each set at different times using rst.MoveNext, etc?
I don't know if I've ever done that but yes that will work. Now you may run into page locking problems if you are updating records in both recordsets. A 4 Kb Access page can and, usually does, contain multiple records. If you are adding records then that's less of an issue as Access 2000 and newer, that is Jet 4.0, appears to add new records in individual pages.
Hey.
I have the main access database located on a stand alone PC off the network and i have a access database with linked tables on the network linked back to the stand alone PC. I have linked the tables by creating a network share to the stand alone PC and linking them though a path. Can i set it up so that when the database is opened it automatically updates the linked tables.
Ben
You can. I often find it convenient to use a small check form that runs on start-up (set through start-up options) and checks a variety of things, including linked tables. To this end, I also hold a table of linked tables on the local machine, although a list of linked tables can be obtained by iterating through the TableDefs collection, I think it is slightly safer to keep a list.
The check form can check all links and if a link is broken or missing, either ask the user for a new location or use a fixed location. If no problems are found, the form can close itself and open a menu or other form.
In the case of linking to a linked table, it is possible to get the connection to use from:
CurrentDB.TableDefs("TableName").Connection
Here are some more notes:
Sub RelinkTables(Optional strConnect As String = "")
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL
Dim tdf As DAO.TableDef
On Error GoTo TrapError
Set db = CurrentDb
If strConnect = "" Then
''Where Me.txtNewDataDirectory is a control on the check form
strConnect = "MS Access;PWD=databasepassword;DATABASE=" & Me.txtNewDataDirectory
End If
''Table of tables to be linked with two fields TableName, TableType
Set rs = CurrentDb.OpenRecordset("Select TableName From sysTables " _
& "WHERE TableType = 'LINK'")
Do While Not RS.EOF
''Check if the table is missing
If IsNull(DLookup("[Name]", "MSysObjects", "[Name]='" & rs!TableName & "'")) Then
Set tdf = db.CreateTableDef(RS!TableName, dbAttachSavePWD, _
rs!TableName, strConnect)
''If the table is missing, append it
db.TableDefs.Append tdf
Else
''If it exists, update the connection
db.TableDefs(rs!TableName).Connect = strConnect
End If
db.TableDefs(rs!TableName).RefreshLink
RS.MoveNext
Loop
Set db = Nothing
RS.Close
Set RS = Nothing
Exit_Sub:
Exit Sub
TrapError:
HandleErr Err.Number, Err.Description, "Relink Tables"
End Sub