Вы можете использовать объединенный запрос:
SELECT a.* INTO NewTable FROM (
SELECT [Code], [Year], "Category1" As Cat, Category1 As CatVal FROM MyTable
UNION ALL
SELECT [Code], [Year], "Category2" As Cat, Category2 As CatVal FROM MyTable
UNION ALL
<...> ) As a
Вы можете исключить зарезервированное слово "Год", пока оно у вас: http://support.microsoft.com/kb/321266
Если у вас много категорий, вы можете использовать VBA, чтобы облегчить жизнь, например:
Sub UnionSQL(ArrayColCommonWord As String, TableName As String)
Dim db As Database
Set db = CurrentDb
For Each fld In db.TableDefs(TableName).Fields
If Left(fld.Name, Len(ArrayColCommonWord)) <> ArrayColCommonWord Then
sSQL1 = sSQL1 & ",[" & fld.Name & "]"
End If
Next
sSQL1 = "SELECT " & Mid(sSQL1, 2)
For Each fld In db.TableDefs(TableName).Fields
If Left(fld.Name, Len(ArrayColCommonWord)) = ArrayColCommonWord Then
sSQL = sSQL & vbCrLf & "UNION ALL" & vbCrLf
sSQL = sSQL & sSQL1 & ",'" & fld.Name & "' As " & ArrayColCommonWord _
& ",[" & fld.Name & "] As " & ArrayColCommonWord & "Val"
sSQL = sSQL & vbCrLf & "FROM [" & TableName & "]"
End If
Next
Debug.Print Mid(sSQL, 14)
''This will fail if there is an existing query
db.CreateQueryDef ArrayColCommonWord, Mid(sSQL, 14)
DoCmd.OpenQuery ArrayColCommonWord, acViewDesign
End Sub