Access「テーブル移行」按钮调查日志
Copyright Notice: This article is an original work licensed under the CC 4.0 BY-NC-ND license.
If you wish to repost this article, please include the original source link and this copyright notice.
Source link: https://v2know.com/article/1322
摘要
本次调查对象是 Access 数据库 C:\Workspace_New\shori-jokyo-management-functions\処理状況等管理システム.accdb 中启动窗体 メインスイッチボード 上的按钮 テーブル移行。
结论是:该按钮不是网页迁移时误造出来的,它是真实存在于 Access 窗体中的命令按钮。控件名为 dataConvert,标题为 テーブル移行。但是它不应该出现在普通第一画面中,因为原 Access 系统通过 autoexec 宏调用 proctest(),根据启动参数 Command 控制该按钮是否可见。
- 当
Command = 1时,dataConvert.Visible = True,按钮显示。 - 当
Command不是1时,dataConvert.Visible = False,按钮隐藏。 - 普通启动 Access 时通常没有
/cmd 1参数,所以原版第一画面不会显示该按钮。
该按钮有实际作用,而且是高风险维护功能:点击后会提示“全テーブルを削除します。よろしいですか?”,用户确认后会删除当前数据库中除 MSys 系统表以外的所有表,然后执行保存的导入任务 インポート-処理状況等管理システム(R020625) 重新导入数据。
网页迁移时的处理结论是:保留该按钮定义,但默认 visible: false,以匹配 Access 普通启动后的第一画面。
超具体的内容
1. 控件本身确实存在
通过 Access COM 打开数据库并枚举 メインスイッチボード 窗体控件后,确认存在如下控件:
Name = dataConvert
Caption = テーブル移行
ControlType = 104
Left = 737
Top = 8163
Width = 1706
Height = 397
OnClick = [Event Procedure]
其中 ControlType = 104 表示 Access 的命令按钮。因此,テーブル移行 不是网页侧新增的按钮,而是原 Access 窗体中已有控件。
2. 为什么普通画面中不显示
数据库中存在 autoexec 宏。该宏启动时执行:
Action = RunCode
Argument = proctest()
proctest() 位于标准模块 DataConvert,代码如下:
Option Compare Database
Function proctest()
If Command = 1 Then
Form_メインスイッチボード.dataConvert.Visible = True
Else
Form_メインスイッチボード.dataConvert.Visible = False
End If
End Function
关键条件是 Command = 1。这对应 Access 启动参数。也就是说,只有类似下面这种启动方式才会显示按钮:
MSACCESS.EXE "処理状況等管理システム.accdb" /cmd 1
普通双击打开数据库,或没有指定 /cmd 1 时,Command 不等于 1,因此执行隐藏逻辑:
Form_メインスイッチボード.dataConvert.Visible = False
3. 按钮点击事件
dataConvert 的点击事件定义在 メインスイッチボード 窗体模块中:
Private Sub dataConvert_Click()
If MsgBox("全テーブルを削除します。よろしいですか?", vbYesNo + vbExclamation + vbDefaultButton2, "データ取込") = vbYes Then
Call FncDataConv
End If
Exit Sub
End Sub
点击按钮后,Access 先弹出确认框:
- 消息:
全テーブルを削除します。よろしいですか? - 标题:
データ取込 - 按钮:Yes / No
- 默认按钮:No,因为使用了
vbDefaultButton2
只有用户选择 Yes 时,才会调用:
Call FncDataConv
4. FncDataConv 的核心逻辑
FncDataConv() 的核心代码如下:
Function FncDataConv()
On Error Resume Next
Dim iCnt As Integer 'レコード件数
Dim Rst As DAO.Recordset 'レコードセット
Dim strSQL As String
Dim var(10000) As String
Dim dbs
Dim i
Set dbs = CurrentDb
For i = dbs.TableDefs.Count - 1 To 0 Step -1
If InStr(dbs.TableDefs(i).Name, "Msys") > 0 Then
Else
'テーブル削除
dbs.TableDefs.Delete dbs.TableDefs(i).Name
'var(i) = dbs.TableDefs(i).Name
End If
Next
dbs.TableDefs.Refresh
Set dbs = Nothing
'データインポート
Call FncDBImport
这段代码的实际行为非常明确:
- 取得当前数据库:
Set dbs = CurrentDb - 倒序遍历所有
TableDefs - 如果表名包含
Msys,认为是系统表,跳过 - 否则执行
dbs.TableDefs.Delete dbs.TableDefs(i).Name删除表 - 刷新表定义集合
- 调用
FncDBImport执行数据导入
所以该按钮的实际作用不是普通“导入”,而是“删除所有非系统表后重新导入”。
5. FncDBImport 的实际导入任务
FncDBImport() 定义在标准模块 DBImport 中:
Option Compare Database
'------------------------------------------------------------
' DBImport
'
'------------------------------------------------------------
Function FncDBImport()
On Error GoTo FncDBImport_Err
DoCmd.RunSavedImportExport "インポート-処理状況等管理システム(R020625)"
FncDBImport_Exit:
Exit Function
FncDBImport_Err:
MsgBox Error$
Resume FncDBImport_Exit
End Function
实际执行的是 Access 保存的导入任务:
インポート-処理状況等管理システム(R020625)
这表示系统并不是在 VBA 中逐表写入导入逻辑,而是调用 Access 内部保存的 Import/Export 规范。
6. 完成后的统计和提示
导入完成后,FncDataConv() 会统计当前用户表数量:
strSQL = "SELECT Count(*) AS CNT FROM MSysObjects WHERE MSysObjects.Type=1 AND MSysObjects.Flags=0"
Set Rst = CurrentDb.OpenRecordset(strSQL)
iCnt = Rst![cnt]
随后显示完成消息:
MsgBox "データの取込を完了しました。" & vbCr & "テーブル移行件数は、" & iCnt & "件 です", vbInformation + vbOKOnly, "レコード移行"
显示内容为:
データの取込を完了しました。
テーブル移行件数は、{iCnt}件 です
7. 风险判断
该按钮是维护/迁移模式按钮,风险较高,原因如下:
- 删除表阶段使用了
On Error Resume Next,错误可能被忽略。 - 删除条件只排除了名称包含
Msys的系统表。 - 所有业务表、导入表、临时表,只要名称不包含
Msys,都会进入删除逻辑。 - 删除后完全依赖保存的导入任务
インポート-処理状況等管理システム(R020625)恢复数据。
8. 网页迁移处理
网页端应该模拟普通 Access 启动状态,也就是:
Form_メインスイッチボード.dataConvert.Visible = False
因此迁移后的网页实现保留按钮定义,但默认不渲染:
Button("テーブル移行", 737, 8163, 1706, 397, visible: false)
渲染按钮时只输出可见按钮:
@foreach (var button in Buttons.Where(button => button.Visible))
{
<button type="button" class="@ButtonClass(button)" style="@ButtonStyle(button)">
@HtmlText(button.Caption)
</button>
}
这个处理同时满足两个目标:保留原 Access 系统中的真实维护功能信息,但普通第一画面不显示该维护按钮。
This article was last edited at