update if true and add new if false, criteria problem - vba

Here is what i want: I'm making a code to generate invoices data automatically for me when i select month and year then click cmdbtn; but if customerID with the selected date ([Forms]![F_Reports_Slct]![MnthSlct]) and (....![YrSlct]) exists, then update the values instead of creating new record.
Everything here works fine except editing records if matched criteria..
my data is being recreated again when clicked.
I guess I have some problem with criteria.
Note that rsM and rsY are queries, and that the table's recordset ( rs ) has a primary key field with auto numbering [CrId].
Dim msg1 As Variant
Dim db As Database
Dim qdM As QueryDef
Dim qdY As QueryDef
Dim rs As Recordset
Dim rsM As Recordset
Dim rsY As Recordset
Dim lngID As Long
Dim Mcr As String
Dim Ycr As String
Dim strCriteria As String
If IsNull([Forms]![F_Reports_Slct]![YrSlct]) Or IsNull([Forms]![F_Reports_Slct]![MnthSlct]) Then
MsgBox "please enter data"
Cancel = True
Else
Set db = CurrentDb
Set qdM = db.QueryDefs("QC_MonthlyAm4CuID_Tr")
Set qdY = db.QueryDefs("QC_YrlyAm4CuID_Tr")
qdM.Parameters(0).Value = [Forms]![F_Reports_Slct]![YrSlct].Value
qdM.Parameters(1).Value = [Forms]![F_Reports_Slct]![MnthSlct].Value
qdY.Parameters(0).Value = [Forms]![F_Reports_Slct]![YrSlct].Value
qdY.Parameters(1).Value = [Forms]![F_Reports_Slct]![MnthSlct].Value
Mcr = qdM.Parameters(1).Value
Ycr = qdM.Parameters(0).Value
Set rs = db.OpenRecordset("T_CrofServices", dbOpenDynaset)
Set rsM = qdM.OpenRecordset(dbOpenDynaset)
Set rsY = qdY.OpenRecordset(dbOpenDynaset)
msg1 = MsgBox("sure?", vbYesNo + vbExclamation, "Are You Sure?")
If msg1 = vbNo Then
Cancel = True
ElseIf msg1 = vbYes Then
If Not rsM.BOF Then
rsM.MoveFirst
Do Until rsM.EOF
lngID = rsM!CuId & Mcr & Ycr
strCriteria = rs!TrDtCuID = " & lngID"
rs.FindFirst strCriteria
If rs.NoMatch Then
rs.AddNew
Else
rs.Edit
End If
rs![CuId] = rsM![CuId]
rs![CollectorID] = rsM![CollectorID]
rs![Amount] = rsM![MonthlyAm]
rs![DateofCr] = rsM![DateofCr]
rs![TrDtCuID] = rsM!CuId & Mcr & Ycr
rs![TrDt] = rsM![DtTr]
rs.Update
rsM.MoveNext
Loop
End If
If Not rsY.BOF Then
rsY.MoveFirst
Do Until rsY.EOF
lngID = rsY!CuId & Mcr & Ycr
strCriteria = "[TrDtCuID]=' & lngID'"
rs.FindFirst strCriteria
If rs.NoMatch Then
rs.AddNew
Else
rs.Edit
End If
rs![CuId] = rsY![CuId]
rs![CollectorID] = rsY![CollectorID]
rs![Amount] = rsY![YrlyAm1]
rs![DateofCr] = rsY![DateofCr]
rs![TrDtCuID] = rsY!CuId & Mcr & Ycr
rs![TrDt] = rsY![DtTr]
rs.Update
rsY.MoveNext
Loop
End If
rs.close
rsM.close
rsY.close
Set rs = Nothing
Set rsM = Nothing
Set rsY = Nothing
Set db = Nothing
Set qdM = Nothing
Set qdY = Nothing
MsgBox "Done.", vbInformation, "Succeed"
End If
End If

I guess I have some problem with criteria.
Yes. You must make up your mind, if you wish to use a Long or a String. Here, you are casting back and forth between these:
lngID = rsM!CuId & Mcr & Ycr
strCriteria = rs!TrDtCuID = " & lngID"
Also, it should read:
strCriteria = "TrDtCuID = " & lngID & ""
Or, if you turn the ID into a string:
strCriteria = "TrDtCuID = '" & strID & "'"

Related

Updating a table based on a findfirst criteria

I have a recordset TBLSOURCETARGETLINK that I want to update on an after update event.
I also need to ensure that no duplicates are present before I add the new record.
If the record exists, I just want to update the record and add new.
I am struggling with the VBA and the sequencing of how to do it.
Please could someone assist.
VBA currently looks like this:
Private Sub IsSource_AfterUpdate()
Dim VbaTableID As Integer
Dim VbaSystemID As Integer
Dim VbaFieldID As Integer
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim tabledef As String
Dim strcriteria As String
Dim rstSourceTarget As Recordset
Set rstSourceTarget = CurrentDb.OpenRecordset(Name:="tblsouretargetlink", Type:=RecordsetTypeEnum.dbOpenDynaset)
If IsNull(Me!TableID) Then
Else
VbaTableID = Me!TableID
End If
If IsNull(Me!SystemID) Then
Else
VbaSystemID = Me!SystemID
End If
If IsNull(Me!FieldID) Then
Else
Vbafield = Me!FieldID
End If
strcriteria = "[systemid] = '" & Me.SystemID & "' And [tableid] = " & Me.TableID And [FieldID] = " & Me.fieldid"
rs.FindFirst strcriteria
If .NoMatch Then
With rstSourceTarget
.AddNew
![SystemID] = VbaSystemID
![SourceTable] = VbaTableID
![SourceField] = VbaFieldID
.Update
End With
Else
With rstSourceTarget
.Edit
![IsSource] = -1
.Update
End If
End Sub
Thank you
Try this code:
Private Sub IsSource_AfterUpdate()
Dim VbaTableID As Integer
Dim VbaSystemID As Integer
Dim VbaFieldID As Integer
Dim db As DAO.Database
Dim strCriteria As String
Dim rstSourceTarget As Recordset
Set db = CurrentDb
' don't use CurrentDb for opening recordsets, it's dynamic, you can lose reference to database.
Set rstSourceTarget = db.OpenRecordset(Name:="tblsouretargetlink", Type:=RecordsetTypeEnum.dbOpenDynaset)
If Not IsNull(Me!TableID) Then
VbaTableID = Me!TableID
End If
If Not IsNull(Me!SystemID) Then
VbaSystemID = Me!SystemID
End If
If Not IsNull(Me!fieldid) Then
VbaFieldID = Me!fieldid
End If
strCriteria = "[systemid] = '" & Me.SystemID & "' And [tableid] = " & Me.TableID & " And [FieldID] = " & Me.fieldid
With rstSourceTarget
.FindFirst strCriteria
If .NoMatch Then
.AddNew
![SystemID] = VbaSystemID
![SourceTable] = VbaTableID
![SourceField] = VbaFieldID
.Update
Else
.Edit
![IsSource] = -1
.Update
End If
End With
End Sub
There are a lot of errors, so first of all add
Option Explicit
at the beginning of each module and recompile the project (Debug->Compile)

Trying to make code more efficient and stable

I have a program, that works, I just feel that it is running slower than it should and I feel that it is a bit more unstable than it should be. I am looking for tips on writing "better" code and making my program more stable.
I am looking to better this part of my code for now:
Private Sub Worksheet_Activate()
Application.ScreenUpdating = False
'Removes shapes already there that will be updated by the getWeather function
For Each delShape In Shapes
If delShape.Type = msoAutoShape Then delShape.Delete
Next delShape
'Calls a function to get weather data from a web service
Call getWeather("", "Area1")
Call getWeather("", "Area2")
Call getWeather("", "Area3")
'Starting to implement the first connection to a SQL Access database.
Dim cn As Object
Dim rs As Object
'Set cn and sqlConnect as ADODB-objects. Set rs as recordset
Set cn = CreateObject("ADODB.Connection")
Set sqlConnect = New ADODB.Connection
Set rs = CreateObject("ADODB.RecordSet")
'Set sqlConnect as connection string
sqlConnect.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\databases\database.accdb;Persist Security Info=False;"
'Open connection string via connection object
cn.Open sqlConnect
'Set rs.Activeconnection to cn
rs.ActiveConnection = cn
'Get a username from the application to be used further down
Brukernavn = Application.userName
'This part of the code re-arranges the date format from american to european
StartDate = Date
EndDate = Date - 7
midStartDate = Split(StartDate, ".")
midEndDate = Split(EndDate, ".")
StartDate2 = "" & midStartDate(1) & "/" & midStartDate(0) & "/" & midStartDate(2) & ""
EndDate2 = "" & midEndDate(1) & "/" & midEndDate(0) & "/" & midEndDate(2) & ""
'SQL statement to get data from the access database
rs.Open "SELECT [RefNr], [Registrert Av],[Nettstasjon], [Meldt Dato] , [Bestilling], [Sekundærstasjon], [Avgang], [Hovedkomponent], [HovedÅrsak], [Status Bestilling] FROM [tblDatabase]" & _
"WHERE [Registrert Av] = '" & Brukernavn & "' AND [Loggtype] <> 'Beskjed' AND [Meldt Dato] BETWEEN #" & StartDate2 & "# AND # " & EndDate2 & "#" & _
"ORDER BY [Meldt Dato] DESC;", _
cn, adOpenStatic
'Start to insert data from access database into a list
Dim i As Integer
Dim u As Integer
If Not rs.EOF Then
rs.MoveFirst
End If
i = 0
With lst_SisteFeil
.Clear
Do
If Not rs.EOF Then
.AddItem
If Not IsNull(rs!refnr) Then
.List(i, 0) = rs![refnr]
End If
If IsDate(rs![Meldt Dato]) Then
.List(i, 1) = Format(rs![Meldt Dato], "dd/mm/yy")
End If
.List(i, 4) = rs![nettstasjon]
If Not IsNull(rs![Sekundærstasjon]) Then
.List(i, 2) = rs![Sekundærstasjon]
End If
If Not IsNull(rs![Avgang]) Then
.List(i, 3) = rs![Avgang]
End If
If Not IsNull(rs![Hovedkomponent]) Then
.List(i, 5) = rs![Hovedkomponent]
End If
If Not IsNull(rs![HovedÅrsak]) Then
.List(i, 6) = rs![HovedÅrsak]
End If
If Not IsNull(rs![Status Bestilling]) Then
.List(i, 7) = rs![Status Bestilling]
End If
If Not IsNull(rs![bestilling]) Then
.List(i, 8) = rs![bestilling]
End If
i = i + 1
rs.MoveNext
Else
GoTo endOfFile
End If
Loop Until rs.EOF
End With
endOfFile:
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
'Starts to connect to SQL access database again to get different set of data. This must be possible to make more efficient?
Dim cn2 As Object
Dim rs2 As Object
'Set cn and sqlConnect as ADODB-objects. Set rs as recordset
Set cn2 = CreateObject("ADODB.Connection")
Set sqlConnect2 = New ADODB.Connection
Set rs2 = CreateObject("ADODB.RecordSet")
'Set sqlConnect as connection string
sqlConnect2.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\databases\database.accdb;Persist Security Info=False;"
'Open connection string via connection object
cn2.Open sqlConnect
'Set rs.Activeconnection to cn
rs2.ActiveConnection = cn2
'Second SQL statement
rs2.Open "SELECT [RefNr], [Registrert Av],[Nettstasjon], [Meldt Dato] , [Bestilling], [Sekundærstasjon], [Avgang], [Hovedkomponent], [HovedÅrsak], [Status Bestilling] FROM [tblDatabase]" & _
"WHERE [Registrert Av] <> '" & Brukernavn & "' AND [Meldt Dato] BETWEEN #" & StartDate2 & "# AND # " & EndDate2 & "#" & _
"ORDER BY [Meldt Dato] DESC;", _
cn2, adOpenStatic
'Inserting into second list
If Not rs2.EOF Then
rs2.MoveFirst
End If
u = 0
With lst_AlleFeil
.Clear
Do
If Not rs2.EOF Then
.AddItem
If Not IsNull(rs2!refnr) Then
.List(u, 0) = rs2![refnr]
End If
If IsDate(rs2![Meldt Dato]) Then
.List(u, 1) = Format(rs2![Meldt Dato], "dd/mm/yy")
End If
.List(u, 4) = rs2![nettstasjon]
If Not IsNull(rs2![Sekundærstasjon]) Then
.List(u, 2) = rs2![Sekundærstasjon]
End If
If Not IsNull(rs2![Avgang]) Then
.List(u, 3) = rs2![Avgang]
End If
If Not IsNull(rs2![Hovedkomponent]) Then
.List(u, 5) = rs2![Hovedkomponent]
End If
If Not IsNull(rs2![HovedÅrsak]) Then
.List(u, 6) = rs2![HovedÅrsak]
End If
If Not IsNull(rs2![Status Bestilling]) Then
.List(u, 7) = rs2![Status Bestilling]
End If
If Not IsNull(rs2![bestilling]) Then
.List(u, 8) = rs2![bestilling]
End If
u = u + 1
rs2.MoveNext
Else
GoTo endOfFile2
End If
Loop Until rs2.EOF
End With
endOfFile2:
rs2.Close
cn2.Close
Set rs2 = Nothing
Set cn2 = Nothing
'Starting to connect to the database for the third time
Dim cn3 As Object
Dim rs3 As Object
'Set cn and sqlConnect as ADODB-objects. Set rs as recordset
Set cn3 = CreateObject("ADODB.Connection")
Set sqlConnect3 = New ADODB.Connection
Set rs3 = CreateObject("ADODB.RecordSet")
'Set sqlConnect as connection string
sqlConnect3.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\databases\database.accdb;Persist Security Info=False;"
'Open connection string via connection object
cn3.Open sqlConnect
'Set rs.Activeconnection to cn
rs3.ActiveConnection = cn3
'third sql statement
rs3.Open "SELECT [RefNr], [Registrert Av],[Nettstasjon], [Meldt Dato], [Sekundærstasjon], [Avgang], [Beskrivelse], [Til Dato] FROM [tblDatabase]" & _
"WHERE [Loggtype] = 'Beskjed' AND [Meldt Dato] >= DateAdd('d',-30,Date())" & _
"ORDER BY [Meldt Dato] DESC;", _
cn3, adOpenStatic
'Inserting data in to third list
If Not rs3.EOF Then
rs3.MoveFirst
End If
j = 0
With lst_beskjeder
.Clear
Do
If Not rs3.EOF Then
.AddItem
If Not IsNull(rs3!refnr) Then
.List(j, 0) = rs3![refnr]
End If
If IsDate(rs3![Meldt Dato]) Then
.List(j, 1) = Format(rs3![Meldt Dato], "dd/mm/yy")
End If
.List(j, 4) = rs3![nettstasjon]
If Not IsNull(rs3![Sekundærstasjon]) Then
.List(j, 2) = rs3![Sekundærstasjon]
End If
If Not IsNull(rs3![Avgang]) Then
.List(j, 3) = rs3![Avgang]
End If
If Not IsNull(rs3![beskrivelse]) Then
.List(j, 5) = rs3![beskrivelse]
End If
j = j + 1
rs3.MoveNext
Else
GoTo endOfFile3
End If
Loop Until rs3.EOF
End With
endOfFile3:
rs3.Close
cn3.Close
Set rs3 = Nothing
Set cn3 = Nothing
End Sub
Here is the function I have used to get weather data.
Public Sub getWeather(APIurl As String, sted As String)
Dim i As Integer
i = 0
Dim omraade As String
omraade = ""
omraade = sted
If sted = "Area1" Then
i = 4
ElseIf sted = "Area2" Then
i = 6
ElseIf sted = "Area3" Then
i = 8
End If
Dim WS As Worksheet: Set WS = ActiveSheet
Dim delShape As Shape
Dim city As String
Dim Req As New XMLHTTP
Req.Open "GET", "" & APIurl & "", False
Req.Send
Dim Resp As New DOMDocument
Resp.LoadXML Req.responseText
Dim Weather As IXMLDOMNode
Dim wShape As Shape
Dim thisCell As Range
For Each Weather In Resp.getElementsByTagName("current_condition")
Set thisCell = WS.Range(Cells(2, i), Cells(2, i))
Set wShape = WS.Shapes.AddShape(msoShapeRectangle, thisCell.Left, thisCell.Top, thisCell.Width, thisCell.Height)
wShape.Fill.UserPicture Weather.ChildNodes(4).Text 'img
Cells(3, i).Value = "" & Weather.ChildNodes(7).Text * 0.28 & " m/s" 'windspeedkmph
Cells(4, i).Value = Weather.ChildNodes(9).Text 'Direction
Cells(5, i).Value = Weather.ChildNodes(1).Text & " C" 'observation time
Next Weather
End Sub
Feel free to point out any poor coding and tips on how to improve it. I am currently using the Worksheet Activate sub to activate changes in the tables and get new data, but I suspect that is not the best solution. I am just not sure how else to do it seeing as I want it to be as "automatic" as possible, and use as few buttons to refresh as I can.
Thank you for all the help.
-Thomas
Some tips, but none will affect performance, only help make your code more succinct.
1.
rs.Open "SELECT ..."
If Not rs.EOF Then
rs.MoveFirst
End If
.MoveFirst is unnecessary. After opening a recordset, you are always on the first record, if there are records.
When building complex SQL in VBA, have a look at How to debug dynamic SQL in VBA.
2.
Don't do a Do ... Until loop for recordsets:
Do
If Not rs.EOF Then
' do stuff for each record
' ...
rs.MoveNext
Else
GoTo endOfFile
End If
Loop Until rs.EOF
endOfFile:
rs.Close
Instead use Do While Not rs.EOF :
Do While Not rs.EOF
' do stuff for each record
' ...
rs.MoveNext
Loop
rs.Close
For an empty rs, the loop will not be entered. You don't need the If/Else and the Goto.

VBA Access Inserting from One DAO.Recordset into Another

Within the following code
Dim sqlStr As String
Dim OrgID As Long
Dim wrk As DAO.Workspace
Dim db As DAO.Database
Dim orgRS As DAO.Recordset
Dim staffRS As DAO.Recordset
Set wrk = DBEngine.Workspaces(0)
Set db = CurrentDb
On Error GoTo trans_Err
InsertOrganizationIntoTemp
'if staff fields are not blank Insert Staff into Temp
If (addStaffClickCheck = True) Then
staffNumber = staffNumber + 1
InsertStaffIntoTemp staffNumber
End If
wrk.BeginTrans
sqlStr = "INSERT INTO tblOrganization(OrganizationName, Affiliate, " _
& " UnionCouncil, DateJoined, OrganizationPhoneNumber, OrganizationFaxNumber, " _
& " MembershipGroup, TradeGroup, URL) " _
& " SELECT OrganizationName, Affiliate, CouncilUnion, DateJoined, OrganizationPhone, " _
& " OrganizationFax, MemberGroup, Trade, OrganizationWebsite " _
& " FROM tblTempOrganization;"
db.Execute sqlStr
OrgID = db.OpenRecordset("SELECT ##IDENTITY")(0)
sqlStr = "INSERT INTO tblAddresses(StreetName, CityName, StateName, " _
& " ZipCode, LocationID, OrganizationID) " _
& " SELECT OrganizationAddress, OrganizationCity, OrganizationState, " _
& " OrganizationZIP, OrganizationLocationType, '" & OrgID & "' " _
& " FROM tblTempOrganization;"
db.Execute sqlStr
'pull all staff and phones into two recordsets
'loop through staff and for each staff member add associated phone information
'Recordsets for temporary staff tables
Dim staffTempInfoRS As DAO.Recordset
Dim phoneTempInfoRS As DAO.Recordset
Set staffTempInfoRS = db.OpenRecordset("SELECT * FROM tblTempStaff", dbOpenDynaset)
'Recordsets for permanant staff tables
Dim StaffAddressID As Long
Dim StaffID As Long
'Check to see if the recordset actually contains rows
If Not (staffTempInfoRS.EOF And staffTempInfoRS.BOF) Then
staffTempInfoRS.MoveFirst 'Unnecessary in this case, but still a good habit
Do Until staffTempInfoRS.EOF = True
'address information
Dim staffAddressDBRS As DAO.Recordset
Set staffAddressDBRS = db.OpenRecordset("tblStaffAddresses", dbOpenDynaset)
With staffAddressDBRS
.AddNew
.Fields("StaffStreet") = staffTempInfoRS.Fields("StaffStreet")
.Fields("StaffCity") = staffTempInfoRS.Fields("StaffCity")
.Fields("StaffState") = staffTempInfoRS.Fields("StaffState")
.Fields("StaffZip") = staffTempInfoRS.Fields("StaffZip")
.Update
End With
StaffAddressID = staffAddressDBRS.LastModified
staffAddressDBRS.Close
Set staffAddressDBRS = Nothing
'staff information
Dim staffInfoDBRS As DAO.Recordset
Set staffInfoDBRS = db.OpenRecordset("tblStaff", dbOpenDynaset)
With staffInfoDBRS
.AddNew
.Fields("StaffFirstName") = staffTempInfoRS.Fields("StaffFirstName")
.Fields("StaffLastName") = staffTempInfoRS.Fields("StaffLastName")
.Fields("Email") = staffTempInfoRS.Fields("Email")
.Fields("StaffAddressID") = StaffAddressID
.Fields("OrganizationID") = OrgID
.Fields("Position") = staffTempInfoRS.Fields("StaffPosition")
.Update
End With
Dim currPos As Long
currPos = staffTempInfoRS.Fields("StaffNumber")
StaffID = staffInfoDBRS.LastModified
staffInfoDBRS.Close
Set staffInfoDBRS = Nothing
'staff phone information
Set phoneTempInfoRS = db.OpenRecordset("SELECT * FROM tblTempPhones WHERE StaffNumber = " & currPos & ";")
If Not (phoneTempInfoRS.EOF And phoneTempInfoRS.BOF) Then
phoneTempInfoRS.MoveFirst 'Unnecessary in this case, but still a good habit
Do Until phoneTempInfoRS.EOF = True
Dim phoneInfoDBRS As DAO.Recordset
Set phoneInfoDBRS = db.OpenRecordset("tblStaffPhoneNumbers", dbOpenDynaset)
With phoneInfoDBRS
.AddNew
.Fields("PhoneNumber") = phoneTempInfoRS.Fields("StaffPhoneNumber")
.Fields("PhoneTypeID") = phoneTempInfoRS.Fields("PhoneType")
.Fields("StaffID") = StaffID
.Update
End With
phoneTempInfoRS.MoveNext
Loop
Else
Resume Next
End If
MsgBox "Finished looping through phone records."
phoneTempInfoRS.Close
Set phoneTempInfoRS = Nothing
'Move to the next record. Don't ever forget to do this.
staffTempInfoRS.MoveNext
Loop
Else
MsgBox "There are no records in the staff recordset."
End If
MsgBox "Finished looping through staff records."
staffTempInfoRS.Close 'Close the recordset
Set staffTempInfoRS = Nothing 'Clean up
wrk.CommitTrans
trans_Exit:
'Clean up
wrk.Close
Set db = Nothing
Set wrk = Nothing
Exit Function
trans_Err:
'Roll back the transaction
MsgBox "Whoops! We got errors"
wrk.Rollback
Resume trans_Exit
When I step through this I get an error in this line:
.Fields("StaffStreet") = staffTempInfoRS.Fields("StaffStreet")
That says:
Item not found in collection.
However, this is the exact field name that is in the table that the recordset is set to open.
30 hours later it seems I suffered a rookie mistake and in-spite of repeated checking missed that the field names were indeed misspelled.
I also set the recordsets outside of the loops and I unset them all in the exit snippet...

3146 ODBC Call Failed - Access 2010

Please reference code below...
Private Sub Save_Click()
On Error GoTo err_I9_menu
Dim dba As Database
Dim dba2 As Database
Dim rst As Recordset
Dim rst1 As Recordset
Dim rst2 As Recordset
Dim rst3 As Recordset
Dim SQL As String
Dim dateandtime As String
Dim FileSuffix As String
Dim folder As String
Dim strpathname As String
Dim X As Integer
X = InStrRev(Me!ListContents, "\")
Call myprocess(True)
folder = DLookup("[Folder]", "Locaton", "[LOC_ID] = '" & Forms!frmUtility![Site].Value & "'")
strpathname = "\\Reman\PlantReports\" & folder & "\HR\Paperless\"
dateandtime = getdatetime()
If Nz(ListContents, "") <> "" Then
Set dba = CurrentDb
FileSuffix = Mid(Me!ListContents, InStrRev(Me!ListContents, "."), 4)
SQL = "SELECT Extension FROM tbl_Forms WHERE Type = 'I-9'"
SQL = SQL & " AND Action = 'Submit'"
Set rst1 = dba.OpenRecordset(SQL, dbOpenDynaset, dbSeeChanges)
If Not rst1.EOF Then
newname = Me!DivisionNumber & "-" & Right(Me!SSN, 4) & "-" & LastName & dateandtime & rst1.Fields("Extension") & FileSuffix
Else
newname = Me!DivisionNumber & "-" & Right(Me!SSN, 4) & "-" & LastName & dateandtime & FileSuffix
End If
Set moveit = CreateObject("Scripting.FileSystemObject")
copyto = strpathname & newname
moveit.MoveFile Me.ListContents, copyto
Set rst = Nothing
Set dba = Nothing
End If
If Nz(ListContentsHQ, "") <> "" Then
Set dba2 = CurrentDb
FileSuffix = Mid(Me.ListContentsHQ, InStrRev(Me.ListContentsHQ, "."), 4)
SQL = "SELECT Extension FROM tbl_Forms WHERE Type = 'HealthQuestionnaire'"
SQL = SQL & " AND Action = 'Submit'"
Set rst3 = dba2.OpenRecordset(SQL, dbOpenDynaset, dbSeeChanges)
If Not rst3.EOF Then
newname = Me!DivisionNumber & "-" & Right(Me!SSN, 4) & "-" & LastName & dateandtime & rst3.Fields("Extension") & FileSuffix
Else
newname = Me!DivisionNumber & "-" & Right(Me!SSN, 4) & "-" & LastName & dateandtime & FileSuffix
End If
Set moveit = CreateObject("Scripting.FileSystemObject")
copyto = strpathname & newname
moveit.MoveFile Me.ListContentsHQ, copyto
Set rst2 = Nothing
Set dba2 = Nothing
End If
Set dba = CurrentDb
Set rst = dba.OpenRecordset("dbo_tbl_EmploymentLog", dbOpenDynaset, dbSeeChanges)
rst.AddNew
rst.Fields("TransactionDate") = Date
rst.Fields("EmployeeName") = Me.LastName
rst.Fields("EmployeeSSN") = Me.SSN
rst.Fields("EmployeeDOB") = Me.EmployeeDOB
rst.Fields("I9Pathname") = strpathname
rst.Fields("I9FileSent") = newname
rst.Fields("Site") = DLookup("Folder", "Locaton", "Loc_ID='" & Forms!frmUtility!Site & "'")
rst.Fields("UserID") = Forms!frmUtility!user_id
rst.Fields("HqPathname") = strpathname
rst.Fields("HqFileSent") = newname2
rst.Update
Set dba = Nothing
Set rst = Nothing
exit_I9_menu:
Call myprocess(False)
DivisionNumber = ""
LastName = ""
SSN = ""
ListContents = ""
ListContentsHQ = ""
Exit Sub
err_I9_menu:
Call myprocess(False)
MsgBox Err.Number & " " & Err.Description
'MsgBox "The program has encountered an error and the data was NOT saved."
Exit Sub
End Sub
I keep getting an ODBC call error. The permissions are all correct and the previous piece of code worked where there were separate tables for the I9 and Hq logs. The routine is called when someone submits a set of files with specific information.
Just a guess here, but I'm thinking you've got a typo that's resulting in assigning a Null to a required field.
Change "Locaton":
rst.Fields("Site") = DLookup("Folder", "Locaton", "Loc_ID='" & Forms!frmUtility!Site & "'")
To "Location":
rst.Fields("Site") = DLookup("Folder", "Location", "Loc_ID='" & Forms!frmUtility!Site & "'")
Some general advice for troubleshooting 3146 ODBC Errors: DAO has an Errors collection which usually contains more specific information for ODBC errors. The following is a quick and dirty way to see what's in there. I have a more refined version of this in a standard error handling module that I include in all of my programs:
Dim i As Long
For i = 0 To Errors.Count - 1
Debug.Print Errors(i).Number, Errors(i).Description
Next i
I solved this by recreating the table in SQL instead of up-sizing it out of Access.
My 3146 error was caused by the lack of primary key on my sql server table. It was resolved by defining a primary key and then refreshing the connection through Linked Table Manager.

How to run a SQL Query from Excel in VBA on changing a Dropdown

I'm trying to create a dropdown that upon changing the selection from the list of options will run a query that will insert the query results into the page. Here's what I have thus far:
Sub DropDown1_Change()
Dim dbConnect As String
Dim leagueCode As String
Dim leagueList As Range
Dim leagueVal As String
Dim TeamData As String
Set leagueList = Worksheets("Menu Choices").Range("A5:A10")
Set leagueVal = Worksheets("Menu Choices").Cell("B1").Value
leagueCode = Application.WorksheetFunction.Index(leagueList, leagueVal)
TeamData = "SELECT DISTINCT(Teams.teamID), name FROM Teams WHERE lgID = '" & leagueCode & "' & ORDER BY name ASC"
With Worksheets("Menu Choices").QueryTables.Add(Connection:=dbConnect, Destination:=Worksheets("Menu Choices").Range("D5"))
.CommandText = TeamData
.Name = "Team List Query"
.Refresh BackgroundQuery:=False
End With
End Sub
Anywho have any suggestions to get it working? Thanks in advance!
I was able to resolve the issue using similar code to the following:
Sub createTeamList()
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim SQL As String
Dim inc As Integer
Dim topCell As Range
Dim leagueID As String
Dim leagueList As Range
Dim leagueChoice As Range
Set leagueList = Worksheets("Menu Choices").Range("A4:A9")
Set leagueChoice = Worksheets("Menu Choices").Range("B1")
leagueID = Application.WorksheetFunction.Index(leagueList, leagueChoice)
Set topCell = Worksheets("Menu Choices").Range("D4")
With topCell
Range(.Offset(1, 0), .Offset(0, 1).End(xlDown)).ClearContents
End With
With cn
.ConnectionString = "Data Source=" & ThisWorkbook.Path & "\lahman_57.mdb"
.Provider = "Microsoft Jet 4.0 OLE DB Provider"
.Open
End With
inc = 0
SQL = "SELECT teamID, name " _
& "FROM Teams " _
& "WHERE lgID = '" & leagueID & "' " _
& "GROUP BY teamID, name " _
& "ORDER BY name "
rs.Open SQL, cn
With rs
Do Until .EOF
topCell.Offset(inc, 0) = .Fields("teamID")
topCell.Offset(inc, 1) = .Fields("name")
inc = inc + 1
.MoveNext
Loop
End With
rs.Close
cn.Close
End Sub