Updating a table based on a findfirst criteria - vba

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)

Related

How do I edit a recordset if it already exists and add a recordset if there isn't one yet in vba? [duplicate]

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)

update if true and add new if false, criteria problem

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 & "'"

Excel VBA Adding records below existing values

I've been developing a little tool that query's our database and returns some references.
I'm having a problem adding the newly query'd values below already existing values in the excel Sheet1.
Option Explicit
Public Ref As String
Const DWConnectString = "Provider=SQLOLEDB... "
Public Property Get rRef() As String
rRef = Me.TextBox1.Value
Ref = Trim(rRef)
End Property
Private Sub TextBox1_Change()
Dim rRef As String
rRef = Me.TextBox1.Value
End Sub
Private Sub ZoekRef_Click()
Dim cn As Object
Dim rs As Object
Dim cm As Object
Dim Ref As String
Dim StrSource As String
Dim startrow As Integer
Ref = rRef
Set cn = CreateObject("ADODB.Connection")
cn.Open DWConnectString
Set rs = CreateObject("ADODB.Recordset")
'rs = New ADODB.Recordset
StrSource = "Select CONSIGNMENT.CONSIGNMENT, CONSIGNMENT.DOCUMENT_REMARK_2, INVOICE_HIST.NET_AMOUNT, INVOICE_HIST.VAT_AMOUNT, INVOICE_HIST.INV_CURRENCY "
StrSource = StrSource & "from CONSIGNMENT left outer join INVOICE_HIST ON CONSIGNMENT.CONSIGNMENT=INVOICE_HIST.CONSIGNMENT "
StrSource = StrSource & "where DOCUMENT_REMARK_2 like '%"
StrSource = StrSource & Ref & "%'"
rs.Open StrSource, cn
If rs.EOF Then
MsgBox "Geen Resultaten"
Exit Sub
Else
Dim fieldNames, j
rs.MoveFirst
ReDim fieldNames(rs.Fields.Count - 1)
For j = 0 To rs.Fields.Count - 1
fieldNames(j) = rs.Fields(j).Name
Next
Sheet1.Range(Sheet1.Cells(1, 1), Sheet1.Cells(1, rs.Fields.Count)).Value = fieldNames
For j = 1 To rs.Fields.Count
Sheet1.Columns(j).AutoFit
Next
Sheet1.Cells.CopyFromRecordset rs
'fldcount2 = Sheets("sheet1").UsedRange.Rows.Count
Sheet1.Rows(1).Insert
Sheet1.Range(Sheet1.Cells(1, 1), Sheet1.Cells(1, rs.Fields.Count)).Value = fieldNames
startrow = 3
Do Until rs.EOF
rs.MoveNext
startrow = startrow + 1
Loop
End If
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
End Sub
I thought about using the line:
Do until trim(cells(startrow,1).Value) = ""
startrow = startrow + 1
Loop
Before the rs.Movenext lines, but that seems to test the recordset, not the actual excel file.
Can I test my current Sheet1's values before adding the new recordset so it comes below what's already existing?
Thanks for the help.
Expand the scope of your loop.
rs.MoveFirst
Do Until rs.EOF
'Do all your work here
'Then increment your counter and the recordset
rs.MoveNext
startrow = startrow + 1
Loop

How to save the result of a SQL query into a variable in VBA?

I want to execute a select statement and put the result of it (which is only 1 record with 1 value) in a variable.
This is in VBA code in access.
Private Sub Child_Click()
Dim Childnummer As Integer
Dim childnaam As String
Childnummer = Me.Keuzelijst21.Value
DoCmd.Close
DoCmd.OpenForm "submenurubrieken", acNormal, , " rubrieknummer = " & Childnummer & ""
childnaam = rubrieknaamSQL(Childnummer)
Forms!submenurubrieken.Tv_rubrieknaam.Value = childnaam
End Sub
Public Function rubrieknaamSQL(Child As Integer)
Dim rst As DAO.Recordset
Dim strSQL As String
strSQL = "SELECT rubrieknaam FROM dbo_tbl_rubriek where rubrieknummer = " & Child & ""
Set rst = CurrentDb.OpenRecordset(strSQL)
End Function
Simply have your Function return the value from the Recordset:
Public Function rubrieknaamSQL(Child As Integer)
Dim rst As DAO.Recordset
Dim strSQL As String
strSQL = "SELECT rubrieknaam FROM dbo_tbl_rubriek where rubrieknummer = " & Child & ""
Set rst = CurrentDb.OpenRecordset(strSQL)
' new code:
rubrieknaamSQL = rst!rubrieknaam
rst.Close
Set rst = Nothing
End Function
You can do this in pretty much one line by using the "DLookup" Function
rubrieknaam = Nz(DLookup("rubrieknaam ", "dbo_tbl_rubriek ", rubrieknummer & " =[Child]"), 0)
where Child is the ID of the record you are looking for.

Assistance with excel macro using multiple files

I have two excel files with related data.
I am trying to create a macro that will be able to query data from db.xls and fill data.xls with the proper values.
Hope the image will be self-explanatory.
I did not use excel macros until now so any suggestions are appreciated.
Thanks,
Alex
The core function
Private Function GetValues(dataFilePath$, dbFilePath$) As String
'///add a reference
'1. Microsoft ActiveX Data Objects 2.8 Library
Dim cn1 As New ADODB.Connection, cn2 As New ADODB.Connection
Dim rs1 As New ADODB.Recordset, rs2 As New ADODB.Recordset
Dim resultstring$, pos&, sql$
Call dbConnect_xls(cn1, dataFilePath)
Call dbConnect_xls(cn2, dbFilePath)
Set rs1 = cn1.Execute("select *from [Sheet1$];")
While Not rs1.EOF
sql = "select *from [sheet1$] where type='" & rs1.Fields(0).Value & "';"
Set rs2 = cn2.Execute(sql)
While Not rs2.EOF
Dim rcount&, tmp$
rcount = rs2.Fields.Count
For pos = 0 To rcount - 1
tmp = tmp & vbTab & rs2.Fields(pos).Value
Next
resultstring = resultstring & tmp & vbCrLf
tmp = ""
rs2.MoveNext
Wend
rs2.Close
rs1.MoveNext
Wend
rs1.Close
cn1.Close
cn2.Close
GetValues = resultstring
End Function
the connecttion handler
Private Function dbConnect_xls(dbConn As ADODB.Connection, dbPath As String) As Boolean
On Error GoTo dsnErr
With dbConn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & dbPath & ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
.Open
End With
dbConnect_xls = True
Exit Function
dsnErr:
Err.Clear
If dbConn.State > 0 Then dbConn.Close: Call dbConnect_xls(dbConn, dbPath)
dbConnect_xls = False
End Function
And the tester
Public Sub tester()
Dim d1$, d2$
d1 = InputBox("Enter datafile path:")
d2 = InputBox("Enter dbfile path:")
If Dir(d1) <> "" And Dir(d2) <> "" Then
Dim x$
x = GetValues(d1, d2)
MsgBox x
'Call GetValues("C:\data.xls", "C:\db.xls")
Else
MsgBox "Invalid path provided."
End If
End Sub
and could be invoked from immediate window
tester
Hope this helps.