Я пытаюсь объединить несколько полей из одной таблицы, которая содержит идентификатор пользователя и 10 столбцов данных, расположенных горизонтально, чтобы отобразить их в двух полях вертикально, одно из которых будет соответствовать идентификатору пользователя, а другое — 10 вертикальным полям. Во второй таблице имя пользователя будет повторяться столько раз, сколько есть входных данных в 10 горизонтальных полях исходной таблицы.
Мой пример вкратце таков:
MainT
`````
User ID
otherfields
Invoice1
:
Invoice10
Хочу поместить в новую таблицу:
InvoicesT
`````````
User ID
Invoices
Мне нужно знать, как получить данные из MainT:
User | Othr Fld | Invoice1 | Invoice2 | Invoice3
--------+---------------+---------------+---------------+-------------
1 | JF | Paid | Past Due | Civil Court
2 | JN | Paid | Paid | Past Due
3 | MO | Past Due | Paid | Paid
для заполнения InvoicesT в порядке, который я предписал.
User | Invoice
--------+--------------
1 | Paid
1 | Past Due
1 | Civil Court
2 | Paid
2 | Past Due
и т. д.
решение1
Я не помню, чтобы был хотя бы один простой запрос, который мог бы преобразовать данные так, как вам нужно. Первое, что пришло мне в голову, был Crosstab Query, однако это не то, что вы можете сделать, используя имеющуюся у вас структуру данных. Я хотел бы дать вам решение VBA, так как я чувствую, что вы идете по правильному пути в перепроектировании данных вашей таблицы.
Чтобы это решение работало, сначала создайте вторую таблицу InvoicesT
со следующими полями.
InvoicesT
`````````
Field Name | Data Type
--------------------+------------------
invoiceID | Autonumber
UserID | Number
InvoiceCategory | Text
Далее копируем следующую подпрограмму в стандартный модуль.
Public Sub transferData()
Dim oldTbl As DAO.Recordset, newTbl As DAO.Recordset
Dim dbObj As DAO.Database
Dim fCtr As Integer
Set dbObj = CurrentDB()
'Open the MainT table to read the information.
Set oldTbl = dbObj.OpenRecordSet("SELECT [User ID], Invoice1, Invoice2, Invoice3, Invoice4, " & _
"Invoice5, Invoice6, Invoice7, Invoice8, Invoice9, Invoice10 FROM MainT")
'Open the InvoicesT to write new information into.
Set newTbl = dbObj.OpenRecordSet("InvoicesT")
'Loop through the list of all entries in MainT
Do While Not oldTbl.EOF
'This will loop through the fields to create one entry for each field.
'You can change the number 10 to any number depending on the Invoice fields in the table.
For fCtr = 1 To 10
'I have put an IF condition to make sure there are not many empty records for a UserID
'If the Invoice(n) is not available for a particular user, then it does not create an entry.
If Len(oldTbl.Fields("Invoice" & fCtr) & vbNullString) > 0 Then
With newTbl
.AddNew
.Fields("UserID") = oldTbl.Fields(0)
.Fields("InvoiceCategory") = oldTbl.Fields("Invoice" & fCtr)
.Update
End With
End If
Next
'Go to the next record when one user is done with
oldTbl.MoveNext
Loop
'Clean up
Set newTbl = Nothing
Set oldTbl = Nothing
Set dbObj = Nothing
End Sub
Теперь, как только вы сохранили модуль с именем типа mod_TransferTables
и скомпилировали его. Перейдите в свое непосредственное окно (CTRL + G). Затем просто введите transferData
и нажмите ENTER
, это может занять некоторое время в зависимости от количества записей в MainT
таблице. После того, как это будет завершено. У вас должны быть все данные в новой таблице.
Надеюсь это поможет !