Multiple Record Insertion in Microsoft Access through VB - vba

I've created DB within Access and given Data Type "Short Text."
Now I'm trying to prompt record into this table through Visual Basic. I wrote a code so far but need help to fix an error. I'm getting the compile error:
Duplicate declaration in current scope
I can't figure it out what it is?
Option Compare Database
Sub arrayData()
Dim CustomerName() As Variant
Dim num As Integer, dbs As Database, InsertRecord As String
Dim CustomerID As Long, num1 As Long, CustomerName As String
Set dbs = CurrentDb()
CustomerID = 0
For num1 = 0 To 49999
CustomerID = CustomerID + 1
CustomerName = Array("Peter", "Mary")
CustomerAddress = Array("163 City Rd, SOUTHBANK", "65 Orange St, BENTLEIGH EAST")
CustomerPhoneAddress = Array("0416874963", "0478937534")
num = Int((200 - 0 + 1) * Rnd + 0)
CustomerName = CustomerName(num)
CustomerAddress = CustomerAddress(num)
CustomerPhoneNo = CustomerPhoneNo(num)
InsertRecord = "INSERT INTO Customers (CustomerID,CustomerName,CustomerAddress,CustomerPhoneNo) VALUES (" & "'" & CustomerID & "'" & "," & "'" & CustomerName & "'" & "," & "'" & CustomerAddress & "'" & "," & "'" & CustomerPhoneNo & "'" & ")"
dbs.Execute InsertRecord
Debug.Print CustomerID, CustomerName, CustomerAddress, CustomerPhoneNo
Next
End Sub
What can I do in this situation? Any help would be appreciated.

The language you are using is "Visual Basic for Applications" (VBA). This language is line-oriented. It menas that one statement must fit on one single line, unless you are using a line continuation character (_) preceeded by at least one whitespace.
Dim CustomerID As Long, num1 As Long, CustomerName As String, CustomerAddress _
As String, CustomerPhoneNo As String
But I would place the Long and String variables on separate lines and write:
Dim CustomerID As Long, num1 As Long
Dim CustomerName As String, CustomerAddress As String, CustomerPhoneNo As String
The second syntax error is in the InsertRecord = "INSERT INTO ... statement. same problem here. It shoul look like this:
InsertRecord = "INSERT INTO CUSTOMERS (CustomerID,CustomerName," _
& "CustomerAddress,CustomerPhoneNo) VALUES " _
& "(" & "'" & CustomerID & "'" & "," & "'" & CustomerName & "'" & "," & "'" _
& CustomerAddress & "'" & "," & "'" & CustomerPhoneNo & "'" & ")"
Also, what are the - 0 and + 0 good for in Int((200 - 0 + 1) * Rnd + 0). The expression is equivalent to Int(201 * Rnd).
After your edits it seems that you have no line continuations.
THE ERROR IS: You have 2 variables named CustomerName. Variable names must be unique:
Dim CustomerName() As Variant
Dim CustomerName As String
For instance, name the array CustomerNames:
Dim CustomerNames() As Variant
And you should indent your code. It makes it much easier to read.
Sub arrayData()
Dim CustomerName() As Variant
...
CustomerID = 0
For num1 = 0 To 10
CustomerID = CustomerID + 1
...
Debug.Print CustomerID, CustomerName, CustomerAddress, CustomerPhoneNo
Next
End Sub

Related

VBA ACCESS - SQL statement which Counting between 2 columns which are variables

I need a macro in VBA Access. I have a table with all dates of the years like columns (and also the dates are the names of the fields). I've made a form where the user selects two dates, and the macro would count all the data between these 2 columns.
For the example, I put two fixed dates. The problem is I need count between the 2 columns, and the columns can change depending the input of the user. The table is EVOLUTIVO_ASISTENCIA and the field can change depends the user selection. Ihe following code EVOLUTIVO_ASISTENCIA.[" & INICIO_MES_VAR1 & "] is the field "01-01-2023" of the EVOLUTIVO_ASISTENCIA table, but the syntax is wrong and does not function. Can anyone help me?
The code:
Private Sub BUSQUEDA()
Dim CONTEO As String
Dim VAR1 As String
Dim INICIO_MES_VAR1 As Date, TERMINOS_MES_VAR1 As Date
INICIO_MES_VAR1 = Format("01-01-2023", "dd-mm-yyyy")
TERMINOS_MES_VAR1 = Format("31-01-2023", "dd-mm-yyyy")
VAR1 = "VAR1"
CONTEO = "SELECT COUNT(*) FROM EVOLUTIVO_ASISTENCIA " & _
"WHERE EVOLUTIVO_ASISTENCIA.[NOMBRES]='" & VAR1 & "' " & _
** "BETWEEN EVOLUTIVO_ASISTENCIA.[" & INICIO_MES_VAR1 & "] AND EVOLUTIVO_ASISTENCIA.[" & TERMINOS_MES_VAR1 & "]"**
DoCmd.RunSQL CONTEO
End Sub
You don't run a select query, you open it as a recordset. So try:
Private Sub BUSQUEDA()
Dim Records As DAO.Recordset
Dim CONTEO As String
Dim VAR1 As String
Dim INICIO_MES_VAR1 As String
Dim TERMINOS_MES_VAR1 As String
Dim ASISTENCIA_CONTEO As Long
INICIO_MES_VAR1 = "01-01-2023"
TERMINOS_MES_VAR1 = "31-01-2023"
VAR1 = "VAR1"
CONTEO = "SELECT COUNT(*) FROM EVOLUTIVO_ASISTENCIA " & _
"WHERE EVOLUTIVO_ASISTENCIA.[NOMBRES]='" & VAR1 & "' " & _
"BETWEEN EVOLUTIVO_ASISTENCIA.[" & INICIO_MES_VAR1 & "] AND EVOLUTIVO_ASISTENCIA.[" & TERMINOS_MES_VAR1 & "]"
Set Records = CurrentDb.OpenRecordset(CONTEO)
' Read/list/print records.
' Retrieve the value of the first and only field of the first and only record.
ASISTENCIA_CONTEO = Records(0).Value
' Close when done.
Records.Close
End Sub

Variable is crossing different events

Apologies for the vague title, but here is my issue. I have a form that has several select lists and associated text boxes. Basically the way it works is if you select a name from the first list, an AfterUpdate event is triggered to query the DB to see if the Eng_ID and Person_ID already exist in the table. If so, then delete that row then insert the updated row. If there is not any records, then just insert the data. The problem is that when I click a name in the first list, then move to the second list, what's happening is that the the Person_ID of the first list is used for the DLookup query, then it delets the record, then inserts the record of the new person I selected in a different listbox. The code is below: Thanks in advance
' Add/Remove Participant 1
Private Sub lstPar1_AfterUpdate()
Dim n As Integer
Dim strCriteria As String
Dim strSQL As String
With Me.lstPar1
For n = .ListCount - 1 To 0 Step -1
strCriteria = "Eng_ID = " & Nz(Me.Eng_ID, 0) & " And Person_ID = " & .ItemData(n)
If .Selected(n) = False Then
' If a person has been deselected, then delete row from table
If Not IsNull(DLookup("Eng_ID", "tblEngParRole", strCriteria)) Then
strSQL = "DELETE * FROM tblEngParRole WHERE " & strCriteria
CurrentDb.Execute strSQL, dbFailOnError
End If
Else
' If a person has been selected, then insert row into the table
If IsNull(DLookup("Eng_ID", "tblEngParRole", strCriteria)) Then
strSQL = "INSERT INTO tblEngParRole (Eng_ID, Person_ID, ParticipantNumber, Role)" & "VALUES(" & Me.Eng_ID & "," & .ItemData(n) & "," & 1 & ",'" & Me.txtParRole1.Value & "' )"
CurrentDb.Execute strSQL, dbFailOnError
End If
End If
Next n
End With
End Sub
' Add/Remove Participant 2
Private Sub lstPar2_AfterUpdate()
Dim n As Integer
Dim strCriteria As String
Dim strSQL As String
With Me.lstPar2
For n = .ListCount - 1 To 0 Step -1
strCriteria = "Eng_ID = " & Nz(Me.Eng_ID, 0) & " And Person_ID = " & .ItemData(n)
If .Selected(n) = False Then
' If a person has been deselected, then delete row from table
If Not IsNull(DLookup("Eng_ID", "tblEngParRole", strCriteria)) Then
strSQL = "DELETE * FROM tblEngParRole WHERE " & strCriteria
CurrentDb.Execute strSQL, dbFailOnError
End If
Else
' If a person has been selected, then insert row into the table
If IsNull(DLookup("Eng_ID", "tblEngParRole", strCriteria)) Then
strSQL = "INSERT INTO tblEngParRole (Eng_ID, Person_ID, ParticipantNumber, Role) " & "VALUES(" & Me.Eng_ID & "," & .ItemData(n) & "," & 2 & ",'" & Me.txtParRole2.Value & "' )"
CurrentDb.Execute strSQL, dbFailOnError
End If
End If
Next n
End With
End Sub
Using this image, if I select Daniel and enter his role, then the eng_ID, Person_ID, ParticipantNumber and Role are entered into the database as 130, 118, 1, Collaborator.
If I select Kristin, it deletes Daniel becuause it's still using Person_ID of 118 instead of hers which is 134, and since there is a corresponding record, it delets Daniel then adds Kristin.
I don't have Access to test this with, but it seems like you need to separate Participant1 records from Participant2 records when you perform your DLookups.
Also you can generalize your code by pulling the common parts into a separate sub.
Private Sub lstPar1_AfterUpdate()
CheckParticipant Me.lstPar1, 1, Me.txtParRole1.Value
End Sub
Private Sub lstPar2_AfterUpdate()
CheckParticipant Me.lstPar2, 2, Me.txtParRole2.Value
End Sub
Sub CheckParticipant(objList As Object, participantNum As Long, role As String)
Dim n As Integer
Dim strCriteria As String
Dim strSQL As String
With objList
For n = .ListCount - 1 To 0 Step -1
strCriteria = "Eng_ID = " & Nz(Me.Eng_ID, 0) & " And Person_ID = " & .ItemData(n) & _
" And ParticipantNumber=" & participantNum
strSQL = ""
If Not .Selected(n) Then
' If a person has been deselected, then delete row from table
If Not IsNull(DLookup("Eng_ID", "tblEngParRole", strCriteria)) Then
strSQL = "DELETE * FROM tblEngParRole WHERE " & strCriteria
End If
Else
' If a person has been selected, then insert row into the table
If IsNull(DLookup("Eng_ID", "tblEngParRole", strCriteria)) Then
strSQL = "INSERT INTO tblEngParRole (Eng_ID, Person_ID, ParticipantNumber, Role)" & _
" VALUES(" & Me.Eng_ID & "," & .ItemData(n) & "," & participantNum & _
",'" & role & "' )"
End If
End If
If Len(strSQL) > 0 Then CurrentDb.Execute strSQL, dbFailOnError
Next n
End With
End Sub

Microsoft Visual Basic - Run-time error '3075: Syntax error (missing operator) in query expression "1st", 'A', 1-Jan-15', '1')'

I'm trying to add 50,000 records to my Tournament_Result table in Microsoft Access but I have encountered this error: Run-time error '3075: Syntax error (missing operator) in query expression "1st", 'A', 1-Jan-15', '1')'.
Option Compare Database
Option Explicit
Sub arrayData()
Dim TournamentResult() As Variant
Dim DivisionEntered() As Variant
Dim DateOfTournament() As Variant
Dim num As Long, TournamentResultNo As Long, MembershipNo As Long, dbs As Database, InsertRecord As String
Dim num1 As Long 'we need to declare num1 as an Integer to create a loop
Dim TournamentResultDescription As String, DivisionEnteredDescription As String, DateOfTournamentDescription As String
Set dbs = CurrentDb()
TournamentResultNo = 0
MembershipNo = 0
TournamentResultNo = TournamentResultNo + 1
TournamentResult = Array("1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "10th")
DivisionEntered = Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J")
DateOfTournament = Array("1-Jan-15", "2-Feb-15", "3-Mar-15", "4-Apr-15", "5-May-15", "6-Jun-15", "7-July-15", "8-Aug-15", "9-Sep-15", "10-Oct-15", "11-Nov-15", "12-Dec-15")
MembershipNo = MembershipNo + 1
For num1 = 0 To 50000
num = Int((50000 - 0 + 1) * Rnd + 0)
TournamentResultDescription = TournamentResult(num)
DivisionEnteredDescription = DivisionEntered(num)
DateOfTournamentDescription = DateOfTournament(num)
InsertRecord = "insert into TOURNAMENT_RESULT(TournamentResultNo, TournamentResult, DivisionEntered, DateOfTournament, MembershipNo) values (" & "'" & TournamentResultNo & "'" & "," & "'" & TournamentResultDescription & "'" & "'" & "," & "'" & DivisionEnteredDescription & "'" & "," & "'" & DateOfTournamentDescription & "'" & "," & "'" & MembershipNo & "'" & ")"
dbs.Execute InsertRecord
Debug.Print TournamentResultNo; TournamentResultDescription; DivisionEnteredDescription; DateOfTournamentDescription; MembershipNo
Next
End Sub
EDIT: dbs.Execute InsertRecord is highlighted as the problem
Commenters are correct in their suggestions.
These types of dynamic statements can be difficult to debug because of the concatenated strings - and you're making it doubly worse by doing extra concatenation of delimiters and commas.
To me it looks like you just had an extra single quote ("'") in your SQL.
Try:
InsertRecord = _
"insert into TOURNAMENT_RESULT(TournamentResultNo, TournamentResult, DivisionEntered, DateOfTournament, MembershipNo) values ('" & _
TournamentResultNo & "','" & TournamentResultDescription & "','" & _
DivisionEnteredDescription & "','" & DateOfTournamentDescription & _
"','" & MembershipNo & "')"
This is probably what you are after:
Public Function InsertRange()
Const Results As Long = 50000
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
Dim Num101 As Integer
Dim Num102 As Integer
Dim Num12 As Integer
Dim ResultNo As Long
Set dbs = CurrentDb()
Set rst = dbs.OpenRecordset("Select Top 1 * From TOURNAMENT_RESULT")
Randomize
For ResultNo = 1 To Results
Num101 = 1 + Int(10 * Rnd)
Num102 = 1 + Int(10 * Rnd)
Num12 = 1 + Int(12 * Rnd)
rst.AddNew
rst!TournamentResultNo.Value = ResultNo
rst!TournamentResult.Value = CStr(Num101) & "st"
rst!DivisionEntered.Value = Chr(64 + Num102)
rst!DateOfTournament.Value = DateSerial(2015, Num12, Num12)
rst!MembershipNo.Value = ResultNo
rst.Update
Next
rst.Close
Set rst = Nothing
Set dbs = Nothing
End Function

"Duplicate declaration in current scope" error in Access VBA

I'm having an issue with a VBA program I made. I want to create a program which inputs 50,000 records throughout a table (which is the Employee Table in my case), and every time I try to run it, it states an error that says "Compile Error: Duplicate declaration in current scope."
My code is as follows:
Option Compare Database
Option Explicit
Sub arrayData1()
'This subroutine will pump in 50 k records for the first two columns of EMPLOYEE table.
'Also takes in sample names, attempts to clean the data beofre its entered in the table.
'Declare variable by using keyword DIM
Dim EmployeeFNames() As Variant 'implies array. array is always declared variant datatype.
Dim EmployeeLNames() As Variant
Dim EmployeeType() As Variant
Dim num As Integer, dbs As Database, InsertRecord As Variant, num1 As Long
Dim EmployeeID As Long, EmployeeFName As String, EmployeeLName As String, EmployeeType As String, EmployeeWages As Long
'assign value to variables
Set dbs = CurrentDb() 'assign current db(Stage 2 Project)
EmployeeID = 0 'initialise value.
For num1 = 0 To 50000
EmployeeID = EmployeeID + 1 'increment by 1.
EmployeeWages = EmployeeWages + 1
' array is populated with names.
EmployeeFNames = Array("Peter", "Mary", "Frances", "Paul", "Ian", "Ron", "Nathan", "Jesse", "John", "David")
EmployeeLNames = Array("Jacobs", "Smith", "Zane", "Key", "Doe", "Patel", "Chalmers", "Simpson", "Flanders", "Skinner")
EmployeeTypes = Array("Groundskeeper", "Housekeeper", "Concierge", "Front Desk", "Chef", "F&B", "Maintenance", "Accounts", "IT", "Manager")
'Equation for random generation
'INT (upperbound - lowerbound +1) * Rnd + lowerbound) ' upper & lower bound are index values of array
num = Int((9 - 0 + 1) * Rnd + 0) ' equation generates at random a number between 0 & 9.
EmployeeFName = EmployeeFNames(num) ' name is picked at random from array based on random number.
EmployeeLName = EmployeeLNames(num)
EmployeeType = EmployeeTypes(num)
' Use SQL INSERT statement to insert record in EPLOYEE table.
InsertRecord = "INSERT INTO EMPLOYEE(EmployeeID, EmployeeFName, EmployeeLName, EmployeeType, EmployeeWages) VALUES(" _
& "'" & EmployeeID & "'" & "," & "'" & EmployeeFName & "'" & "," & "'" & EmployeeLName & "'" & "," & "'" & EmployeeType & "'" & "," & "'" & EmployeeWages & "'" & ")"
dbs.Execute InsertRecord
Debug.Print EmployeeID; EmployeeFName; EmployeeLName; EmployeeType; EmployeeWages
Next
End Sub
I would appreciate any fixes to this problem and any suggestions towards my code.
You have tried to declare (Dim) the variable EmployeeType as an array of Variant and then later you try to declare it (again) as String.
You'll need to use two different names for those two variables.

Passing Nulls from Excel to SQL

I'm using a VBA Script to update a table in SQL, so far it works perfectly. The problem is when handling null values. Because the VBA script loops until the first column ends, some values are null in the worksheet, but they are placed as zeros in sql.
In Excel:
Name Last name Age
daniel mtz 22
jose mtz 25
John doe
Final result in SQL:
Name Last name Age
daniel mtz 22
jose mtz 25
John doe 0
Any thoughts on how I can tell the Macro or SQL to read them as null and not zero?
P.S, programming each column in sql to place null in the corresponding value is not an option, because this table will be changing constantly and I could have all columns filled, or just some, etc.
[UPDATE] Here is the code for the VBA:
Sub Macro_CargarSQL()
'VARIABLES
Dim conn As New ADODB.Connection
Dim iRowNo As Integer
'Column variables
Dim sname, slastname, sage As String
'CONECTION TO SERVER Y BD
conn.Open "Provider=SQLOLEDB;Data Source=Termxgesvsql07\vfsitesamn;Initial Catalog=DW_PLCO;Integrated Security=SSPI;"
'Import into SQL
With Sheets("test")
'Start row 2
iRowNo = 2
'Delete previous
conn.Execute "delete from table"
'Loop for insert
Do Until .Cells(iRowNo, 1) = ""
sname = .Cells(iRowNo, 1)
slastname = .Cells(iRowNo, 2)
sage = .Cells(iRowNo, 3)
conn.Execute "insert into dbo.table (name, lastname,age ) values ('" & sname & "', '" & slastname & "', '" & sage & "')"
iRowNo = iRowNo + 1
Loop
End With
conn.Close
Set conn = Nothing
End Sub
One way I've done this is to create two SQL strings and do checks on the actually values.
You can do this as follows (generally this is a lot easier if you have an array as you can write an iteration through your values/fieldnames).
Do Until .Cells(iRowNo, 1) = ""
sName = .Cells(iRowNo, 1)
slastname = .Cells(iRowNo, 2)
sage = .Cells(iRowNo, 3)
Dim sqlStrStart As String
Dim sqlStrValues As String
Dim sqlStrFull As String
sqlStrStart = "insert into dbo.table ("
sqlStrValues = " values ("
'build string dynamically (generally I do this using parameters, but this will work)
If sName <> "" Then
sqlStrStart = sqlStrStart + "name,"
sqlStrValues = sqlStrValues + sName & ","
End If
If slastname <> "" Then
sqlStrStart = sqlStrStart + "lastname,"
sqlStrValues = sqlStrValues + slastname & ","
End If
If sName <> "" Then
sqlStrStart = sqlStrStart + "age,"
sqlStrValues = sqlStrValues + sage & ","
End If
'remove last comma
sqlStrStart = Left(sqlStrStart, Len(sqlStrStart) - 1)
sqlStrValues = Left(sqlStrValues, Len(sqlStrValues) - 1)
'close parenthesis
sqlStrStart = sqlStrStart & ")"
sqlStrValues = sqlStrValues & ")"
'combine
sqlStrFull = sqlStrStart + sqlStrValues + ";"
conn.Execute sqlStrFull
iRowNo = iRowNo + 1
Loop
The best way is to create a function that inspects whether a cell value is empty or not. When empty, output should be "null", but when not, enclose the value in between single quotes.
This function can also be used so you can escape values that has single quote in it (such as "O'Brien"). Otherwise, in your current code, you'll encounter a SQL error.
Here's the function:
Function toSQL(s)
If s = "" Then toSQL = "null" Else toSQL = "'" & Replace(s, "'", "''") & "'"
End Function
And here's the replacement Insert statement:
conn.Execute "insert into dbo.table (name, lastname,age ) values (" & toSQL(sname) & ", " & toSQL(slastname) & ", " & toSQL(sage) & ")"
If you consistently call the toSQL function, and also consistently define the column in the SQL database as nullable, you'll be set. If the data type is numeric, you may not want to call toSQL though.
Use this when setting a null value in Excel VBA, and pass that to the SQL parameter's value.
DBNull.Value