VBA 将 Access 数据库导出到 Excel
VBA Exporting Access DB to Excel
我最近建立了一个 MS Access 数据库,希望能简化工作中一些基于纸张的流程。我以前从未使用过 Access 或在 VBA 中编写过任何代码,如果我的代码看起来很糟糕,请提前致歉。
数据库按预期工作,现在我正在努力将一些管理报告导出到 Excel。管理团队希望将数据导出到特定格式的 Excel sheet 而不是 Access 报告。
导出与此表单上测试按钮的 onClick
事件有关
思路是将表单子表单中显示的每件唯一装备都记录在单元格[C7:C14]
中,理论上记录的唯一装备永远不会超过8件。注意:我实际上并不是 运行 任何针对子表单的代码,我一直在使用其他 table 来获取我需要的数据,使用表单上的值作为键。
我已经能够获得以下代码来正确执行此操作
tagNo = """" + Tag_Number.Value + """"
EqSQL = "SELECT Equipment.Equipment_Name,Equipment.Tag_No FROM Equipment WHERE (((Equipment.Tag_No)=" & tagNo & "))"
EquipmentCell = 7
ResponseCell = 7
Set db = CurrentDb
Set rs = db.OpenRecordset(EqSQL, dbOpenDynaset, dbSeeChanges)
Do Until rs.EOF
EquipmentCellSt = ("c" & EquipmentCell)
With wsheet
.Range(EquipmentCellSt).Value = rs![Equipment_Name]
End With
EquipmentCell = (EquipmentCell + 1)
rs.MoveNext
Loop
下一个任务是导出响应值,因此第一台设备需要将其所有响应值依次插入 [J7:AF7]
,下一台设备需要插入 [J8:AF8]
等等。
我有一个名为 Inspection_Detail 的 table,它通过子表单更新并包含我认为为此需要的所有数据。
到目前为止,我的想法是我需要在当前循环中嵌套另一个循环并执行一个 SQL 查询来提取响应值,但我这辈子都弄不明白。
我写了一个 SQL 查询来抓取正确的记录(有些值现在是硬代码)
SELECT Export_Table.Equipment_Name, Export_Table.Task_No,
Export_Table.Response, Export_Table.Notes, Export_Table.Tag_No
FROM Export_Table
WHERE (((Export_Table.Equipment_Name)="Pipe")
AND ((Export_Table.Task_No)="A.1 Equipment")
AND ((Export_Table.Tag_No)="scriptTest"));
我不确定如何构建一个循环计数器来遍历 [J*:AF*]
并且我不知道如何从 SQL 查询
中提取响应值
抱歉,如果我遗漏了任何重要的东西,或者只是完全没有意义,我整个周末都被困在这个问题上,我的大脑被炸了。
以示例为指导,我假设任务将始终是顺序的(没有间隙),但并非所有任务总是有响应。该示例仅显示设备组可能的 9 个中的 1 到 5,安装组仅显示可能的 12 个中的 1 到 3。看看这是否能让你接近:
Dim rsResp As DAO.Recordset
Dim Row As Integer, Col As Integer
Row = 7
Col = 2
With wsheet
.Cells(Row, Col).value = rsEquip![Tag_No]
Col = 10
Set rsResp = CurrentDb.OpenRecordset("SELECT Response FROM Export_Table ORDER BY Task_No " & _
"WHERE Task_No LIKE 'A*' AND Tag_No = '" & Me.Tag_No & "';")
While Not rsResp.EOF
.Cells(Row, Col).value = rsResp!Response
rsResp.Next
Col = Col + 1
Wend
rsResp.Close
Set rsResp = CurrentDb.OpenRecordset("SELECT Response FROM Export_Table ORDER BY Task_No " & _
"WHERE Task_No LIKE 'B*' AND Tag_No = '" & Me.Tag_No & "';")
Col = 19
While Not rsResp.EOF
.Cells(Row, Col).value = rsResp!Response
rsResp.Next
Col = Col + 1
Wend
rsResp.Close
Set rsResp = CurrentDb.OpenRecordset("SELECT Response FROM Export_Table ORDER BY Task_No " & _
"WHERE Task_No LIKE 'C*' AND Tag_No = '" & Me.Tag_No & "';")
Col = 31
While Not rsResp.EOF
.Cells(Row, Col).value = rsResp!Response
rsResp.Next
Col = Col + 1
Wend
Row = Row + 1
Col = 2
rsResp.Close
rsEquip.MoveNext
但是,工作表只允许 8 个项目行。看起来需要一些代码来确定在记录集中检索了多少项并插入适当的行数。
实际上,您可能只需要 C7
单元格上的 crosstab query and then CopyRecordset,填写空白列以对应 Excel 格式:
交叉表查询
TRANSFORM MAX(e.Response) AS Response_Value
SELECT e.Equipment_Name, '' AS BlankD, '' AS BlankE, '' AS BlankF,
'' AS BlankG, '' AS BlankH, '' AS BlankI
FROM Export_Table e
WHERE e.Tag_No = 'ScriptTest'
GROUP BY e.Equipment_Name
PIVOT e.Task_No
(由于单元格合并,可能会缩短空白列,您可能需要 LEFT JOIN
在 Task_No 的详尽列表中,如查找 table 以填写即使 NULL
)
也需要全部 Excel 个单元格
VBA
Set db = CurrentDb
Set rs = db.OpenRecordset("CrossTabQuery")
With wsheet
.Range("C7").CopyFromRecordset rs
End With
rs.Close()
Set rs = Nothing
Set db = Nothing
对于动态查询使用参数化 QueryDefs:
SQL
PARAMETERS Tag_No_Param TEXT;
TRANSFORM MAX(e.Response) AS Response_Value
SELECT e.Equipment_Name, '' AS BlankD, '' AS BlankE, '' AS BlankF,
'' AS BlankG, '' AS BlankH, '' AS BlankI
FROM Export_Table e
WHERE e.Tag_No = [Tag_No_Param]
GROUP BY e.Equipment_Name
PIVOT e.Task_No
VBA
Dim db As Database
Dim qdef As QueryDef, rs As Recordset
Set db = CurrentDb
Set qdef = db.QueryDefs("CrossTabQuery")
qdef![Tag_No_Param] = "ScriptTest" ' DYNAMIC VALUE
Set rs = qdef.OpenRecordset()
With wsheet
.Range("C7").CopyFromRecordset rs
End With
rs.Close()
Set rs = Nothing
Set qdef = Nothing
Set db = Nothing
我最近建立了一个 MS Access 数据库,希望能简化工作中一些基于纸张的流程。我以前从未使用过 Access 或在 VBA 中编写过任何代码,如果我的代码看起来很糟糕,请提前致歉。
数据库按预期工作,现在我正在努力将一些管理报告导出到 Excel。管理团队希望将数据导出到特定格式的 Excel sheet 而不是 Access 报告。
导出与此表单上测试按钮的 onClick
事件有关
思路是将表单子表单中显示的每件唯一装备都记录在单元格[C7:C14]
中,理论上记录的唯一装备永远不会超过8件。注意:我实际上并不是 运行 任何针对子表单的代码,我一直在使用其他 table 来获取我需要的数据,使用表单上的值作为键。
我已经能够获得以下代码来正确执行此操作
tagNo = """" + Tag_Number.Value + """"
EqSQL = "SELECT Equipment.Equipment_Name,Equipment.Tag_No FROM Equipment WHERE (((Equipment.Tag_No)=" & tagNo & "))"
EquipmentCell = 7
ResponseCell = 7
Set db = CurrentDb
Set rs = db.OpenRecordset(EqSQL, dbOpenDynaset, dbSeeChanges)
Do Until rs.EOF
EquipmentCellSt = ("c" & EquipmentCell)
With wsheet
.Range(EquipmentCellSt).Value = rs![Equipment_Name]
End With
EquipmentCell = (EquipmentCell + 1)
rs.MoveNext
Loop
下一个任务是导出响应值,因此第一台设备需要将其所有响应值依次插入 [J7:AF7]
,下一台设备需要插入 [J8:AF8]
等等。
我有一个名为 Inspection_Detail 的 table,它通过子表单更新并包含我认为为此需要的所有数据。
到目前为止,我的想法是我需要在当前循环中嵌套另一个循环并执行一个 SQL 查询来提取响应值,但我这辈子都弄不明白。
我写了一个 SQL 查询来抓取正确的记录(有些值现在是硬代码)
SELECT Export_Table.Equipment_Name, Export_Table.Task_No,
Export_Table.Response, Export_Table.Notes, Export_Table.Tag_No
FROM Export_Table
WHERE (((Export_Table.Equipment_Name)="Pipe")
AND ((Export_Table.Task_No)="A.1 Equipment")
AND ((Export_Table.Tag_No)="scriptTest"));
我不确定如何构建一个循环计数器来遍历 [J*:AF*]
并且我不知道如何从 SQL 查询
抱歉,如果我遗漏了任何重要的东西,或者只是完全没有意义,我整个周末都被困在这个问题上,我的大脑被炸了。
以示例为指导,我假设任务将始终是顺序的(没有间隙),但并非所有任务总是有响应。该示例仅显示设备组可能的 9 个中的 1 到 5,安装组仅显示可能的 12 个中的 1 到 3。看看这是否能让你接近:
Dim rsResp As DAO.Recordset
Dim Row As Integer, Col As Integer
Row = 7
Col = 2
With wsheet
.Cells(Row, Col).value = rsEquip![Tag_No]
Col = 10
Set rsResp = CurrentDb.OpenRecordset("SELECT Response FROM Export_Table ORDER BY Task_No " & _
"WHERE Task_No LIKE 'A*' AND Tag_No = '" & Me.Tag_No & "';")
While Not rsResp.EOF
.Cells(Row, Col).value = rsResp!Response
rsResp.Next
Col = Col + 1
Wend
rsResp.Close
Set rsResp = CurrentDb.OpenRecordset("SELECT Response FROM Export_Table ORDER BY Task_No " & _
"WHERE Task_No LIKE 'B*' AND Tag_No = '" & Me.Tag_No & "';")
Col = 19
While Not rsResp.EOF
.Cells(Row, Col).value = rsResp!Response
rsResp.Next
Col = Col + 1
Wend
rsResp.Close
Set rsResp = CurrentDb.OpenRecordset("SELECT Response FROM Export_Table ORDER BY Task_No " & _
"WHERE Task_No LIKE 'C*' AND Tag_No = '" & Me.Tag_No & "';")
Col = 31
While Not rsResp.EOF
.Cells(Row, Col).value = rsResp!Response
rsResp.Next
Col = Col + 1
Wend
Row = Row + 1
Col = 2
rsResp.Close
rsEquip.MoveNext
但是,工作表只允许 8 个项目行。看起来需要一些代码来确定在记录集中检索了多少项并插入适当的行数。
实际上,您可能只需要 C7
单元格上的 crosstab query and then CopyRecordset,填写空白列以对应 Excel 格式:
交叉表查询
TRANSFORM MAX(e.Response) AS Response_Value
SELECT e.Equipment_Name, '' AS BlankD, '' AS BlankE, '' AS BlankF,
'' AS BlankG, '' AS BlankH, '' AS BlankI
FROM Export_Table e
WHERE e.Tag_No = 'ScriptTest'
GROUP BY e.Equipment_Name
PIVOT e.Task_No
(由于单元格合并,可能会缩短空白列,您可能需要 LEFT JOIN
在 Task_No 的详尽列表中,如查找 table 以填写即使 NULL
)
VBA
Set db = CurrentDb
Set rs = db.OpenRecordset("CrossTabQuery")
With wsheet
.Range("C7").CopyFromRecordset rs
End With
rs.Close()
Set rs = Nothing
Set db = Nothing
对于动态查询使用参数化 QueryDefs:
SQL
PARAMETERS Tag_No_Param TEXT;
TRANSFORM MAX(e.Response) AS Response_Value
SELECT e.Equipment_Name, '' AS BlankD, '' AS BlankE, '' AS BlankF,
'' AS BlankG, '' AS BlankH, '' AS BlankI
FROM Export_Table e
WHERE e.Tag_No = [Tag_No_Param]
GROUP BY e.Equipment_Name
PIVOT e.Task_No
VBA
Dim db As Database
Dim qdef As QueryDef, rs As Recordset
Set db = CurrentDb
Set qdef = db.QueryDefs("CrossTabQuery")
qdef![Tag_No_Param] = "ScriptTest" ' DYNAMIC VALUE
Set rs = qdef.OpenRecordset()
With wsheet
.Range("C7").CopyFromRecordset rs
End With
rs.Close()
Set rs = Nothing
Set qdef = Nothing
Set db = Nothing