I have an access 2013 table that houses one field with comma separated values. I have created a second table that I need to parse the results into with a structure like so
uPPID number
value1 short text
value2 short text
value3 short text
value4 short text
I am dynamically creating the table so it will always have enough "value" fields to accommodate for the number that will be parsed out. Sample data is like such:
uppID values
aeo031 boat, goat, hoat, moat
And I would want the field mappings to go like such
uPPID = aeo031
value1 = boat
value2 = goat
value3 = hoat
value4 = moat
How can access vba parse out a csv list from one field to many?
There are probably faster/better solutions than the follwing VBA loop that inserts records one by one in the destination table. But for instance it does the job.
TableCSV is the name of the source table
TableFields is the name of the destination table
The constant maxValues specifies the number of fields values available
The query composes dynamically the INSERT INTO statement after composing the values fields; it completes it to provide all the columns, and adds the surrounding quotes '...'. (p.s. it could be simplified if we can insert without specifying all column values..)
.
Sub splitTable()
Const maxValues As Long = 4 ' <-- Set to number of value fields in destination table
Dim query As String, values As String, rs
Set rs = CurrentDb.OpenRecordset("TableCSV")
Do Until rs.EOF
values = rs!values ' next we add commas to provide all fields
values = values & String(maxValues - UBound(Split(values, ",")) - 1, ",")
values = "'" & Replace(values, ",", "','") & "'" ' 'a', 'b', '', '' etc
query = "INSERT INTO TableFields VALUES (" & rs!uPPID & "," & values & ")"
Debug.Print query
CurrentDb.Execute query
rs.moveNext
Loop
End Sub
Related
I would like to add a auto sequential number under STOP # field. I have fields as Route, Direction, Stop #, & location. So for example M1 going North has 10 stops (1-10) and vice versa for South bound.
You can use the RowNumber function from my article:
Sequential Rows in Microsoft Access
' Builds consecutive row numbers in a select, append, or create query
' with the option of a initial automatic reset.
' Optionally, a grouping key can be passed to reset the row count
' for every group key.
'
' 2018-08-23. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function RowNumber( _
ByVal Key As String, _
Optional ByVal GroupKey As String, _
Optional ByVal Reset As Boolean) _
As Long
' Uncommon character string to assemble GroupKey and Key as a compound key.
Const KeySeparator As String = "¤§¤"
' Expected error codes to accept.
Const CannotAddKey As Long = 457
Const CannotRemoveKey As Long = 5
Static Keys As New Collection
Static GroupKeys As New Collection
Dim Count As Long
Dim CompoundKey As String
On Error GoTo Err_RowNumber
If Reset = True Then
' Erase the collection of keys and group key counts.
Set Keys = Nothing
Set GroupKeys = Nothing
Else
' Create a compound key to uniquely identify GroupKey and its Key.
' Note: If GroupKey is not used, only one element will be added.
CompoundKey = GroupKey & KeySeparator & Key
Count = Keys(CompoundKey)
If Count = 0 Then
' This record has not been enumerated.
'
' Will either fail if the group key is new, leaving Count as zero,
' or retrieve the count of already enumerated records with this group key.
Count = GroupKeys(GroupKey) + 1
If Count > 0 Then
' The group key has been recorded.
' Remove it to allow it to be recreated holding the new count.
GroupKeys.Remove (GroupKey)
Else
' This record is the first having this group key.
' Thus, the count is 1.
Count = 1
End If
' (Re)create the group key item with the value of the count of keys.
GroupKeys.Add Count, GroupKey
End If
' Add the key and its enumeration.
' This will be:
' Using no group key: Relative to the full recordset.
' Using a group key: Relative to the group key.
' Will fail if the key already has been created.
Keys.Add Count, CompoundKey
End If
' Return the key value as this is the row counter.
RowNumber = Count
Exit_RowNumber:
Exit Function
Err_RowNumber:
Select Case Err
Case CannotAddKey
' Key is present, thus cannot be added again.
Resume Next
Case CannotRemoveKey
' GroupKey is not present, thus cannot be removed.
Resume Next
Case Else
' Some other error. Ignore.
Resume Exit_RowNumber
End Select
End Function
I am trying to use the query below to insert a concatenated converted set of integers to string for use on a datetime field in my table.
TABLE
Field Type
empID int(11)
time_stamp datetime
in_out char(3)
am_pm char(2)
QUERY
Dim query As String = "INSERT INTO attendance VALUES(" & empID.Text & _
"STR_TO_DATE(CONCAT("& empYear.Text & ",'-'," & empMonth.Text & ",'-'," & _
empDay.Text & ",' '," & empHour.Text & ",':'," & empMin.Text & ",':'," & _
empSec.Text & ",'%Y-%m-%d %H:%i:%s'),'out','pm')"
There is no problem with the connection and the values. I have tried to insert the values into a test column of string type and the output is this:
133201712311827
I am pretty sure it's with how I use these characters: '' "" "," - :. I just can't figure out how.
First problem I see, here
& empID.Text & "STR_TO_DATE(. . . .
you're missing comma after first value
& empID.Text & "***,*** STR_TO_DATE(. . . .
Second issue, I identified when I've replaced your text values with hard coded values - You are missing closing parenthesis for str_to_date. Here ,'%Y-%m-%d... should be ), '%Y-%m-%d...
STR_TO_DATE(CONCAT(1999,'-',01,'-',01,' ',10,':',25,':',30***)***,'%Y-%m-%d %H:%i:%s')
As you see- my replacement shows that you have no issues with concatenation, single quote and :. Theo only other variable here is quality of data in text boxes.
Update
This answer (above) is correct. Using sql fiddle I created schema and when replaced text box values with hard-coded ones - all worked. My suggestions to add comma and parenthesis hold true. Your claim about problems with single quotes are false.
create table xxx (empID int(11), time_stamp datetime, in_out char(3), am_pm char(2));
INSERT INTO xxx VALUES(123,
STR_TO_DATE(CONCAT('2017','-','1','-','23',' ','10',':','35',':','40'),'%Y-%m-%d %H:%i:%s'),
'out','pm');
commit;
Select * from xxx
empID | time_stamp | in_out | am_pm
123 | January, 23 2017 10:35:40 | out | pm
End Update
On top of that, you could do it much better by parameterizing, which will look like something like this
command.CommandText = "insert into ... values (#1, #2, #3, #4)"
command.Parameters.AddWithValue("#1", Convert.ToInt32(empID.Text))
dim date as new DateTime(Convert.ToInt32(empYear.Text), Convert.ToInt32(empMonth.Text), . . . . )
command.Parameters.AddWithValue("#2", date)
. . . . . .
command.ExecuteNonQuery()
Parameterizing will make it easy to work with dates and strings
Recently at the company where I work I've needed to import a bunch of orders from excel into our database so that they can be processed and shipped. Many of these excel documents have hundreds of columns. I'm looking for a clean way to convert multiple rows and columns containing order data into a dump of SQL queries.
Here is what I'm working with.
Each order is a single row identified by the OrderID, and the quantity of each product is defined in the cell which corresponds to the ProductID.
I'm using the following formula to convert each cell (if filled) into a value for an SQL query:
=CONCATENATE(IF(ISBLANK(B3),"",("("&B3&", "&B$1&", "&$A3&"), ")))
The result for each filled cell is something like:
(1, 22, 1),
What I want to be able to do, is concatenate each cell (if filled) into one long string per order without having hundreds of columns filled with the same formula. Like this:
(5, 12, 23), (5, 13, 23), (100, 7, 23), (50, 1, 23), (100, 3, 23),
Thanks.
Try This -
VBA Code
Function InsStr(Product As Range, Order As String, Qty As Range)
Dim tmpString As String: tmpString = ""
Dim tmpCount As Integer: tmpCount = 1
For Each cell In Qty
If cell <> "" Then
If tmpCount > 1 Then tmpString = tmpString & ","
tmpString = tmpString & "(" & cell & "," & Product(tmpCount) & "," & Order & ")"
End If
tmpCount = tmpCount + 1
Next cell
InsStr = tmpString
End Function
and use Formula as =InsStr(B1:X1,A3,B3:X3)
I have a field called Product_Id(type string), which has length of 7 and starting with 0. But while inserting through VBA into a table field of type text the zeros is not getting inserted.
This is the insert query:
dbs.Execute "INSERT INTO tablename (PROD_NBR)VALUES (" & prodID & ");"
I think I have fixed the error - you need to declare the value in single quotes.
The PROD_NBR is a string type and field in the table is text type, then the inserting variable should be declared inside single quotes then double quotes and between two & symbols:
dbs.Execute "INSERT INTO tablename (PROD_NBR)VALUES ('" & prodID & "');"
Responding to #Cherry's answer, the following method is less tedious than a parameterized query, aka prepared statement. prodID can safely contain quotes and other special characters.
With dbs.OpenRecordset("tablename")
.AddNew
.Fields("PROD_NBR") = prodID
.Update
End With
Regarding the "starting with zero" part of your question, do you want PROD_NBR to always be 7 characters, padded with leading 0's? Then replace prodID with:
Right("0000000" & prodID, 7)
I have a insert statement in MS Access which needs to be wrapped in single quotes so that it can be passed as string to a column in another table. here is my insert statement below
Insert into Employee(EmpName,EmpDepartment) Values ('Mike',NULL)
when I wrap I am getting errors arounf 'Mike'
'Insert into Employee(EmpName,EmpDepartment) Values ('Mike',NULL)'
Below is my create table with two primary keys
create table Employee([OBJECTID] AUTOINCREMENT(1, 1), EmpName Text(10), EmpDepartment Text(50), Primary Key (OBJECTID, EmpName))
How can I set default values to EmpName as Mike and Null to EmpDepartment while creating table it self ??
You will need ADO to create a default easily with a standard SQL mode for Access. This will run in VBA.
sSQL = "create table Employee([OBJECTID] AUTOINCREMENT(1, 1), " _
& "EmpName Text(10) default mike, EmpDepartment Text(50), " _
& "Primary Key (OBJECTID, EmpName))"
CurrentProject.Connection.Execute sSQL