MakeTable Query (1 Viewer)

kirkm

Registered User.
Local time
Today, 23:32
Joined
Oct 30, 2008
Messages
1,257
My query has 2 fields. Field2 is a vblf demlimited list.
I would like to make a table where Field1 stays Field1 but the Field2 list becomes a separate field for each item.
Before playing around with a UDF I thought I'd ask here as there may be some existing "Access" way to do this ?
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 07:32
Joined
May 21, 2018
Messages
8,536
Field1 but the Field2 list becomes a separate field for each item
That is probably no better. If field 1 is an ID then you should push the list into a seperate table
In table 1 if you have
1 Cat;Dog;Mouse
2Bird; Fish

Code:
Table 2 should be
SomeForeignKey  ListItem
1               cat
1               dog
1               mouse
2               Bird
2               Fish
 

theDBguy

I’m here to help
Staff member
Local time
Today, 04:32
Joined
Oct 29, 2018
Messages
21,477
No existing Access way to do it, but there may be an existing Excel way to do it.

If you follow @MajP suggestion, you would be able to use a Crosstab query in Access to display the data horizontally in separate columns.
 

kirkm

Registered User.
Local time
Today, 23:32
Joined
Oct 30, 2008
Messages
1,257
Sure, I'll try that. You don't have an example of a crosstab query? I've never seen one.
For table2 I can use Field1 as the foreign key.
Thanks both :)
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 07:32
Joined
May 21, 2018
Messages
8,536
Here is a demo
Table OriginalTable
OriginalTable OriginalTable

ParentIDParentDescriptionListItems
1​
PetsCat;Dog;Fish;Bird
2​
ReptilesFrog;snake;lizard
3​
BirdsEagle;stork;buzzard
Empty new table
NewChildTable NewChildTable

listItemIDListItemParentID_FK
17​
0​
Run this code
Code:
Public Sub SplitList()
  Dim rs As DAO.Recordset
  Dim i As Integer
  Dim arList() As String
  Dim strSql As String
 
  Set rs = CurrentDb.OpenRecordset("originalTable")
  Do While Not rs.EOF
     arList = Split(rs!listitems, ";")
       For i = 0 To UBound(arList)
        strSql = "INSERT INTO NewChildTable (ParentID_FK,ListItem) Values (" & rs!parentID & ", '" & arList(i) & "')"
        CurrentDb.Execute strSql
      Next i
    rs.MoveNext
  Loop
End Sub

Now looks like

NewChildTable NewChildTable

listItemIDListItemParentID_FK
18​
Cat
1​
19​
Dog
1​
20​
Fish
1​
21​
Bird
1​
22​
Frog
2​
23​
snake
2​
24​
lizard
2​
25​
Eagle
3​
26​
stork
3​
27​
buzzard
3​

Use in a query with the original table
qryParentChild qryParentChild

ParentIDParentDescriptionListItem
1​
PetsCat
1​
PetsDog
1​
PetsFish
1​
PetsBird
2​
ReptilesFrog
2​
Reptilessnake
2​
Reptileslizard
3​
BirdsEagle
3​
Birdsstork
3​
Birdsbuzzard
 

Attachments

  • SplitOut.accdb
    448 KB · Views: 187

kirkm

Registered User.
Local time
Today, 23:32
Joined
Oct 30, 2008
Messages
1,257
Thanks for the demo, it was helpful to see that method. But I wasn't able (at least yet) to apply it to the job I had. What I was after was for all the 'list items to have their own field, but horizontally not vertically.
It may not be what a cross tab query does.. I couldn't prove it one way or another as the wizard gave an error about
The table or query you selected doesn't have enough fields to provide data for a crosstab query. Select a table or query with at least 3 numeric, date or text fields.
There were only 2 fields (I didn't have an ID field) so that was that. Tried Googling but only very complex (thus useless) examples found. I got it done though, but by connecting to Excel and using a worksheet.
 

theDBguy

I’m here to help
Staff member
Local time
Today, 04:32
Joined
Oct 29, 2018
Messages
21,477
Thanks for the demo, it was helpful to see that method. But I wasn't able (at least yet) to apply it to the job I had. What I was after was for all the 'list items to have their own field, but horizontally not vertically.
It may not be what a cross tab query does.. I couldn't prove it one way or another as the wizard gave an error about
The table or query you selected doesn't have enough fields to provide data for a crosstab query. Select a table or query with at least 3 numeric, date or text fields.
There were only 2 fields (I didn't have an ID field) so that was that. Tried Googling but only very complex (thus useless) examples found. I got it done though, but by connecting to Excel and using a worksheet.
Hi. A Crosstab query requires three pieces of information: one for the row header, one for the column header, and one for the value. However, that doesn't mean you need three fields for the Crosstab query. You can use the same field in all three or maybe in two of them (if you only have two fields to use).
 

kirkm

Registered User.
Local time
Today, 23:32
Joined
Oct 30, 2008
Messages
1,257
The column header is the field name, yes ? What's a row header ?
 

theDBguy

I’m here to help
Staff member
Local time
Today, 04:32
Joined
Oct 29, 2018
Messages
21,477
The column header is the field name, yes ? What's a row header ?
When you create a Crosstab Query, you need to designate a row heading, column heading, and a value.

1607729460623.png
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 07:32
Joined
May 21, 2018
Messages
8,536
If your max list items is small you can do this with a function. This is pretty inefficient but simple to do
Code:
Public Function GetListItem(VarList As Variant, ItemNumber As Integer, Optional Delimiter As String = ";") As String
  Dim arList() As String
  Dim i As Integer
 
  'Pass in a 1 based item number then convert to 0 based
  ItemNumber = Abs(ItemNumber - 1)
  If Not (VarList & "" = "") Then
    arList = Split(VarList, Delimiter)
    If UBound(arList) >= ItemNumber Then
      GetListItem = arList(ItemNumber)
    End If
  End If
End Function


Used in a query would be like this. It is just cut and paste
Code:
SELECT originaltable.parentid,
       originaltable.parentdescription,
       originaltable.listitems,
       Getlistitem([listitems], 1) AS Item1,
       Getlistitem([listitems], 2) AS Item2,
       Getlistitem([listitems], 3) AS Item3,
       Getlistitem([listitems], 4) AS Item4,
       Getlistitem([listitems], 5) AS Item5
FROM   originaltable;

qryFunction qryFunction

ParentIDParentDescriptionListItemsItem1Item2Item3Item4Item5
1​
PetsCat;Dog;Fish;BirdCatDogFishBird
2​
ReptilesFrog;snake;lizardFrogsnakelizard
3​
BirdsEagle;stork;buzzardEaglestorkbuzzard
 

Attachments

  • SplitOut2.accdb
    528 KB · Views: 175

kirkm

Registered User.
Local time
Today, 23:32
Joined
Oct 30, 2008
Messages
1,257
Using MajP's example in message 5, "Pets" would be the row header? "Cat;Dog;Fish;Bird" would be split by ";" to 4 fields in that row. But what would be the column header? Or it is anything (irrelevant) ?
Is the wizard capable of constructing this, or am I on the wrong track here ?
 

kirkm

Registered User.
Local time
Today, 23:32
Joined
Oct 30, 2008
Messages
1,257
MaJP. ours msgs crossed. Just gettig your db now.,
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 07:32
Joined
May 21, 2018
Messages
8,536
There may be some confusion here, but in order to use a xtab you would have to normalize the data first like I described into rows. The cross tab would not help with the splitting
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 07:32
Joined
May 21, 2018
Messages
8,536
I see in the original post that your list is serperated by a CRLF. Then you need to pass that to the function
Code:
SELECT originaltable.parentid,
       originaltable.parentdescription,
       originaltable.listitems,
       Getlistitem([listitems], 1,Chr(13) + Chr(10)) AS Item1,
       Getlistitem([listitems], 2,Chr(13) + Chr(10)) AS Item2,
       Getlistitem([listitems], 3,Chr(13) + Chr(10)) AS Item3,
       Getlistitem([listitems], 4,Chr(13) + Chr(10)) AS Item4,
       Getlistitem([listitems], 5,Chr(13) + Chr(10)) AS Item5
FROM   originaltable;
where CHr(13) + chr(10) is the vbcrlf
qryFunction qryFunction

parentidparentdescriptionlistitemsItem1Item2Item3Item4
1​
PetsCat
Dog
Fish
bird
CatDogFishbird
2​
ReptilesFrog
Snake
lizard
FrogSnakelizard
3​
BirdsEagle
Stork
Buzzard
EagleStorkBuzzard
 

theDBguy

I’m here to help
Staff member
Local time
Today, 04:32
Joined
Oct 29, 2018
Messages
21,477
Using MajP's example in message 5, "Pets" would be the row header? "Cat;Dog;Fish;Bird" would be split by ";" to 4 fields in that row. But what would be the column header? Or it is anything (irrelevant) ?
Is the wizard capable of constructing this, or am I on the wrong track here ?
Okay, I took the sample file @MajP provided in Post #5 and added the Crosstab Query for you. Hope it helps...

1607787524484.png
 

Attachments

  • SplitOut.zip
    23 KB · Views: 115
Last edited:

MajP

You've got your good things, and you've got mine.
Local time
Today, 07:32
Joined
May 21, 2018
Messages
8,536
To add if you have a lot of data and lots of items the workaround in post 14 would be very inefficient compared to the Xtab shown above. Also that will handle any amount of columns. However, as pointed out you have to use what I posted earlier to create a populate child table.
 

Users who are viewing this thread

Top Bottom