Duplicate row in a table after insert - sql

I have a block of code that imports data from a text file to a table in Access. Each row in the text file should be saved separately in the table, but sometimes I have a duplicate row in the table. For example I have a text file like this:
Water
Bird
Summer
Sometimes and NOT always I see two Summer in the table. Always the last row of the text file is duplicated.
here is my VB code:
Private Sub Command11_Click()
Dim ifile As Integer
Dim db As Database
Dim name As String
Let ifile = FreeFile
name = util1.fDateiName("*.lab", "Lable")
Me.RecordSource = ""
DoCmd.RunSQL ("DELETE * FROM tb_lable_Daten")
Me.RecordSource = "SELECT name FROM tb_lable_Daten"
If name <> "" Then
Open name For Input As ifile
While Not EOF(ifile)
Line Input #ifile, entireline
'MsgBox entireline
DoCmd.RunSQL ("INSERT INTO tb_lable_Daten (name) VALUES ('" & entireline & "');")
Wend
List5.Requery
List5.SetFocus
MsgBox ("Die Daten sind erfolgreich gespeichert")
End If
End Sub
How can I solve this problem? and why does this problem occur?

In my view it seems somehow the file is processing beyond the last
line (which is summer in this case). Since you are not initializing
the varaible i:e entireline during each iteration so for the messed up
case its taking the last valid input (summer in your case). Try to
check and insert if and only if you have a valid value in entireline
variable and then re-initialize the entireline variable to blank after insertion. I hope this will solve the issue.

Related

How do I prompt for a CSV user input on my on-start event for my form?

at work, we're trying to build a database to get an output of all kinds of data from different excel tables (items in stock, sales per week, price, etc) into one table by using the ItemID as primary key for all the tables and as a user input for the queries.
My goal is to let the user enter multiple itemIDs seperated by commas and get back a table with multiple rows (one for each item).
I have now created a form with all the fields I need and have used one of my queries that I implemented before as my data source.
I'm trying to write some code for my On-Start event and have used an example someone posted online regarding entering multiple parameters:
Option Compare Database
Const record source = Query01
Private Sub Form_Open(Cancel As Integer)
Dim m As String
m = InputBox("Enter itemID (numeric), separated by comma", "itemID")
If m <> "" Then
Me.RecordSource = record_source & " where itemID in (" & m & ");"
Else
Me.RecordSource = record_source
End If
End Sub
For the line:
Me.RecordSource = record_source & " where SKU in (" & m & ");"
I get the error
Run-Time error '2580'
The record source 'where SKU in (" & m & ");' specified on this form or report does not exist.
Do I need to declare my record source differently in the second line? Do I need to somehow specify which table I get my "itemID" field out of? The Query01 that I put as my data source gets fields out of three different tables.
Thank you so much for your help!
Cheers!
I fixed my issue by using the Filter-method instead and just deleting the declaration in line 2 since the data source was already defined in the properties sheet before.
My VBA code:
Private Sub Form_Open(Cancel As Integer)
Dim m As String
m = InputBox("Enter itemID (numeric), separated by comma", "itemID")
If m <> "" Then
Me.Filter = "itemID in (" & m & ")"
Me.FilterOn = True
Else
Me.FilterOn = False
End If
End Sub
Hope this helps anyone encountering a similar problem.
Cheers!

How to access selected record column value in nested sub-datasheet form

I spend half day to figure out how to access value in nested datasheet form record.
Please, take a look at image below.
I have dblClick event on "SID" column cell. It's field name is "txtSID".
I need to grab that value (in picture "20") and pass it in VBA SQL.
There is some trick with datasheets. Looks like they has no control name or something.
Looks like I found solution. """ & Me![txtSID] & """ does the thing.
Private Sub txtSID_DblClick(Cancel As Integer)
Dim SQL As String
SQL = "INSERT INTO documents (stakeholder_id, document_type_id, status_id) VALUES (""" & Me![txtSID] & """, 1, 1);"
DoCmd.SetWarnings False
DoCmd.RunSQL SQL
DoCmd.SetWarnings True
End Sub

Excel VBA insert array variable into single field in access

In my project I'm trying to save indefinite entry in excel sheet into the database (access). I'm trying to use vba to do so. However, because I don't know how long the entries will be, and I can't create so many fields in the database to fit the unknown amount of entries. And I can't INSERT an array variable into one field in the table. How can I do this?
Say I have below.
Dim SN(100) As String
SN(0)=123 'value of each entry
SN(1)=2412
'so on and so many entries
Then in the SQL statement,
"INSERT INTO [TableName] ([FieldName]) Values (SN)"
It will say RunTime Error "13" Type mismatch.
Is there any way the database field can accept a list or array as data type? So when I call the data out I can use the index to call the variable inside the list?
MS Access does not have such a data type, more primitive types like string, boolean, long. But consider joining all items in array using Join into a single string and save that string to database table. Then use Split to pull back into array as needed:
Sub ArrayIntoSQL()
Dim SN(100) As String, TN() As String
Dim SNstr As String,
SN(0) = 123 'value of each entry'
SN(1) = 2412
SNstr = Join(SN, "|") ' PIPE DELIMITER '
'123|2412|||||||||||||||||||||||||||||||||||||||||||||_
||||||||||||||||||||||||||||||||||||||||||||||||||||||'
strSQL = "INSERT INTO [TableName] ([FieldName]) Values ('" & SNstr & "')"
...
End Sub
Sub ArrayOutofSQL()
Dim SN() As String
Dim SNstr As String
strSQL = "SELECT [FieldName] FROM [TableName]"
...
Do While Not rst.EOF
SN() = Split(rst!FieldName, "|")
rst.MoveNext
Loop
...
End Sub
Because the array items may exceed Access' 255 character limit for short text data type, use the long text type (previously called memo) which does not have a declared limit.
However for best practices, wide tables (many columns) and stored objects like arrays in fields are more expensive than long tables (many rows) and linked objects. So simply save data iteratively:
For Each item in SN
strSQL = "INSERT INTO [TableName] ([FieldName]) Values (" & item & ")"
...
Next item
Of course, save values with an identifier like ID, Person, Date!

Determining if Spreadsheet Entries Match Database Column Entries

One aspect of my project involves comparing the part number entered by the operator to a predetermined list of part numbers in a column in a database. Right now, my program is telling me that every part number entered in the spreadsheet (50+) does not match any in the database, which I've verified to be incorrect. I've checked that both the spreadsheet part number and the database part number are of string datatype. I've doublechecked that my looping logic is good, and to me seems like it should work. To the best of my knowledge there are no hidden characters in either the database cells or in the spreadsheet cells. I'm completely stumped at this point as to why my program doesn't detect any matches between the spreadsheet and the database. Below is the Sub containing the code for checking that the part numbers match:
Sub CheckPN()
'Connect to the E2 database
Call SetPNConnection
'Open a recordset
Set PNRecordset = New ADODB.Recordset
PNRecordset.Open "EstimRpt", PNConnection, adOpenKeyset, adLockOptimistic, adCmdTable
PNSQLCmd = "SELECT DISTINCT [PartNo] FROM EstimRpt;"
'Loop through data, comparing part numbers to E2 database part number records
TotalBadPNCount = 0
With PNRecordset
For DataRowCount = 2 To TrackingLastRow
PNCount = 0
Part_Number = Tracking.Sheets("Operator Data").Range("A" & DataRowCount).Value
'MsgBox "The datatype for " & Part_Number & " is " & VarType(Part_Number) & "."
Do Until .EOF
'MsgBox "The datatype for " & .Fields("PartNo").Value & " is " & VarType(.Fields("PartNo").Value) & "."
If Part_Number = .Fields("PartNo").Value Then
'If .Fields("PartNo").Value = Part_Number Then
MsgBox Part_Number & " is a match."
PNCount = PNCount + 1
End If
.MoveNext
Loop
If PNCount < 1 Then
MsgBox "The P/N " & Part_Number & " entered in cell A" & DataRowCount & " is incorrect. Please correctly enter the P/N and re-run the program."
TotalBadPNCount = TotalBadPNCount + 1
End If
Next DataRowCount
If TotalBadPNCount >= 1 Then
Exit Sub
End If
End With
PNRecordset.Close
Set PNRecordset = Nothing
PNConnection.Close
Set PNConnection = Nothing
End Sub
On a side note, I'd like to have the entire program stop executing if a part number doesn't match, not just the immediate sub. Currently, just this sub exits upon no part number matches.
Thanks for the help on both of these issues.
Jordan
I'd suggest not using a loop to compare records from your user-submitted dataset to your permanent table. Instead, load the user-submitted dataset into a temporary table in your DB, and use SQL to compare the 2 tables.
You can try something along these lines:
'Load spreadsheet into temp table
<your code here>
'open recordset in order to compare PartNos
Dim db As Database
Set db = CurrentDb
Dim rs As Recordset
sSQL = "select count(*) as [count] from temp " _
& " where temp.PartNo not in (select distinct EstimRpt.PartNo from EstimRpt)"
Set rs = db.OpenRecordset(sSQL)
ctRecords = rs![Count]
'if records are found in temp table that do not exist
'in the perm table, then end execution of everything.
if ctRecords > 0 then
End
else
'run the rest of your code
<your code here>
end if
'Drop temp table
<your code here>
I found my problem at long last. The comparing records between database and spreadsheet does work now. I had to make the following changes to my code:
Instead of:
Do Until .EOF
I needed:
Do Until .EOF = True
I also needed to add the following just after the For Loop declaration:
.MoveFirst
Now my code loops correctly.

VBA to Trim all Cells in an Access Table

I'm relatively experienced with Object oriented programming, but this is my first time ever working in Office with VBA and I'm entirely stumped by the syntax. I've been doing some searching and messing with it for the past hour or so, but have been trouble actually getting a macro that runs successfully and does what I need.
I'm attempting to loop through every cell in an Access table and apply the Trim function to the contents of that cell and, as a bonus, I'd like to remove all extra spaces in the string (if any). I.e. " Trim this__string " would simply become "Trim this string" (I used the underscore there to represent individual, multiple spaces since StackOverflow didn't want to show my multiple spaces).
Any code example of doing something like this, or at least something to get me close and then I can tinker with it, would be greatly appreciated. Thanks!
You can remove leading and trailing spaces with the Trim() function in a query.
UPDATE YourTable
SET text_field = Trim(text_field);
If you will be doing this from within an Access session, you could use Replace() to replace a sequence of two spaces with a single space.
UPDATE YourTable
SET text_field = Replace(text_field, ' ', ' ');
However you may need to run that Replace() query more than once to get all the contiguous space characters down to only one.
You could also do a regular expression-based replacement with a user-defined function. I don't know if that's worth the effort, though. And a user-defined function is also only available from within an Access application session.
I overlooked the "every cell in a table" aspect. That makes this more challenging and I don't think you can solve it with a standard macro or query. You can however use VBA code to examine the TableDef, and iterate through its fields ... then call your Trim and/or Replace operations on any of those fields whose data type is text or memo.
Here's a rough code outline to identify which fields of a given table are text type.
Public Sub FindTextFields(ByVal WhichTable As String)
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Set db = CurrentDb
Set tdf = db.TableDefs(WhichTable)
For Each fld In tdf.Fields
If fld.Type = dbText Or fld.Type = dbMemo Then
Debug.Print "Do something with " & fld.Name
End If
Next
Set fld = Nothing
Set tdf = Nothing
Set db = Nothing
End Sub
Option Compare Database
Private Sub Command3_Click()
Call findField(Text1.Value)
End Sub
Public Function findField(p_myFieldName)
Dim db As Database, _
tb As TableDef, _
fd As Field
'''''''''Clearing the contents of the table
DoCmd.RunSQL "delete * from Field_Match_Found"
Set db = CurrentDb
For Each tb In db.TableDefs
For Each fd In tb.Fields
If fd.Name = p_myFieldName Then
strsql = "INSERT INTO Field_Match_Found Values (""" & tb.Name & """, """ & fd.Name & """)"
DoCmd.RunSQL strsql
End If
Next fd
Next tb
Set fd = Nothing
Set tb = Nothing
Set db = Nothing
If DCount("Account_number", "Field_Match_Found") = 0 Then
MsgBox ("No match was found")
Else
MsgBox ("Check Table Field_Match_Found for your output")
''''''''''making textbox blank for next time
Text1.Value = ""
End Function