搬家第41天-citect2018使用cicode脚本动态创建ODBC连接

前面几天练习了如何使用ODBC方式连接Access数据库,以便后来的数据表操作。当时做练习的目的是学习数据表的读写。实际项目中,项目文件夹的位置不是固定的,最好是根据项目文件夹的位置自动的匹配。为了达到这个目的,我特意的做了练习,把思路和解决办法记录在下面。

首先手动创建一个ODBC链接,名字叫做myaccess,连接上某个Access数据库。打开注册表文件,搜索myaccess关键字,可以看到在下面的位置。

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\myaccess]
"Driver"="C:\\Windows\\system32\\odbcjt32.dll"
"DBQ"="E:\\Citect2018Prj\\Citect2018ReportBaseOnAccess\\report.mdb"
"Description"="连接access数据库"
"DriverId"=dword:00000019
"FIL"="MS Access;"
"SafeTransactions"=dword:00000000
"UID"=""

[HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\myaccess\Engines]

[HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\myaccess\Engines\Jet]
"ImplicitCommitSync"=""
"MaxBufferSize"=dword:00000800
"PageTimeout"=dword:00000005
"Threads"=dword:00000003
"UserCommitSync"="Yes"

[HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\ODBC Data Sources]
"myaccess"="Microsoft Access Driver (*.mdb)"

 

这些注册表信息包含了创建ODBC时各个选项的值。接下来就是想办法在项目运行初期,能够自动的创建这样的注册表文件,尤其是关于access数据库的路径要动态的生成,后台导入注册表,不要人工干预操作。

 新建一个内部变量mypath,用于存放项目路径

新建一个cicode函数,代码如下

FUNCTION CreateODBCLink()
INT sfile,FileClosed,runregfile,sfile1,FileClosed1
FileClosed=10

FileClosed1=10
STRING prjpath,prjfileinreg,regfile,strDBQ,batfile
prjpath=PathToStr("[run]")
regfile=prjpath+"\createODBC.reg"
prjfileinreg=StrReplace(prjpath,"","\")+"report.mdb"
strDBQ="^"DBQ^"=^"" +prjfileinreg+"^""
IF FileExist(regfile) THEN   //判断该文件存在是否存在
  FileDelete(regfile)      //删除该文件
END
sfile=FileOpen(regfile,"a+")
WHILE NOT FileExist(regfile) DO
//循环等待批处理文件生成,但是一个空文件
END
//写注册表文件,配置ODBC连接,自动生成用户DSN
//[HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\myaccess]
FileWrite(sfile,"[HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\myaccess]")
FileWrite(sfile,"^r^n")
//"Driver"="C:\\Windows\\system32\\odbcjt32.dll"
FileWrite(sfile,"^"Driver^"=^"C:\\Windows\\system32\\odbcjt32.dll^"")
FileWrite(sfile,"^r^n")

FileWrite(sfile,strDBQ)
FileWrite(sfile,"^r^n")
//"Description"="连接access数据库"
FileWrite(sfile,"^"Description^"=^"连接access数据库^"")
FileWrite(sfile,"^r^n")
//"DriverId"=dword:00000019
FileWrite(sfile,"^"DriverId^"=dword:00000019")
FileWrite(sfile,"^r^n")
//"FIL"="MS Access;"
FileWrite(sfile,"^"FIL^"=^"MS Access;^"")
FileWrite(sfile,"^r^n")
//"SafeTransactions"=dword:00000000
FileWrite(sfile,"^"SafeTransactions^"=dword:00000000")
FileWrite(sfile,"^r^n")
//"UID"=""
FileWrite(sfile,"^"UID^"=^"^"")
FileWrite(sfile,"^r^n")
//[HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\myaccess\Engines]
FileWrite(sfile,"[HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\myaccess\Engines]")
FileWrite(sfile,"^r^n")
//[HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\myaccess\Engines\Jet]
FileWrite(sfile,"[HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\myaccess\Engines\Jet]")
FileWrite(sfile,"^r^n")
//"ImplicitCommitSync"=""
FileWrite(sfile,"^"ImplicitCommitSync^"=^"^"")
FileWrite(sfile,"^r^n")
//"MaxBufferSize"=dword:00000800
FileWrite(sfile,"^"MaxBufferSize^"=dword:00000800")
FileWrite(sfile,"^r^n")
//"PageTimeout"=dword:00000005
FileWrite(sfile,"^"PageTimeout^"=dword:00000005")
FileWrite(sfile,"^r^n")
//"Threads"=dword:00000003
FileWrite(sfile,"^"Threads^"=dword:00000003")
FileWrite(sfile,"^r^n")
//"UserCommitSync"="Yes"
FileWrite(sfile,"^"UserCommitSync^"=^"Yes^"")
FileWrite(sfile,"^r^n")
//[HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\ODBC Data Sources]
FileWrite(sfile,"[HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\ODBC Data Sources]")
FileWrite(sfile,"^r^n")
//"myaccess"="Microsoft Access Driver (*.mdb)"
FileWrite(sfile,"^"myaccess^"=^"Microsoft Access Driver (*.mdb)^"")
FileWrite(sfile,"^r^n")
FileClosed=FileClose(sfile)

//注册表文件生成完毕,关闭它
WHILE FileClosed<>0 DO
//循环等待文件完全关闭
END

batfile=prjpath+"\importReg.bat"
IF FileExist(batfile) THEN   //判断该文件存在是否存在
  FileDelete(batfile)      //删除该文件
END

sfile1=FileOpen(batfile,"a+")
WHILE NOT FileExist(batfile) DO
//循环等待批处理文件生成,但是一个空文件
END

FileWrite(sfile1,"reg import "+prjpath+"createODBC.reg")
FileClosed1=FileClose(sfile1)
WHILE FileClosed1<>0 DO
//循环等待文件完全关闭
END

END

 

上述函数会获取当前项目的路径,在其下生成一个CreateODBC.REG的注册表文件。还会生成一个importReg.bat批处理文件,其作用是导入CreateODBC.REG文件,不受人工干预,不需要点击确认。项目程序文件夹下需要人工新建一个带有宏的excel文件,RunBat.xlsm。我用的是excel2016,默认的状态是没有启用VBA功能的,需要在菜单文件-选项-自定义功能区中启用“开发工具”。

启用后在菜单栏可以看到开发工具菜单,选择visual basic

就可以写vba代码了。在thisworkbook点击鼠标右键,选择“查看代码”,选择worbook的open事件,表示在工作簿打开的时候执行代码,写以下代码

Private Sub Workbook_Open()

Dim mypath As String

mypath = Application.ActiveWorkbook.Path

Shell mypath & "\importReg.bat", vbMinimizedFocus

End Sub

代码中项目路径也是动态的,就不用担心项目文件夹移动位置了。

 

 

 

前述cicode程序制定一个函数主要是文件读写操作,还包含了双引号字符,回车换行字符,练习的时候这里很是花了点心思。注册表文件生成后,本想通过exec函数来执行,但始终无法执行,返回值是276,说权限不够,我也不知道为什么,也找不到答案。于是转变思路,设计一个excel文件进程,在这个进程里面通过VBA来导入注册表文件。

新建一个citectVBA程序,代码如下:

Sub RunExcelFile()

Dim xlApp As Application

Dim objwb As Object

Set xlApp=CreateObject("excel.application")

xlApp.Visible=false

'打开带有宏的excel文件,宏运行后会自动创建ODBC

Set objwb = xlapp.WorkBooks.Open(prjpath & "RunBatfile.xlsm")

xlApp.Workbooks.Close

xlApp.Quit

Set xlApp=Nothing

End Sub

页面添加一个按钮,按钮的鼠标点击事件写以下脚本

CreateODBCLink()

civba call RunExcelFile()

保存编译,运行后点击这个按钮,就会先创建注册表文件和批处理文件,然后后台执行带宏命令的excel文件,创建用户ODBC了。也可以在项目中创建一个新的页面start,页面尺寸设置为10*10,页面打开事件写入

CreateODBCLink()

civba call RunExcelFile()

pagedisplay("main","cluster1")

 

将项目启动页面设置为start,这样项目运行时,会首先初始化设置ODBC,然后跳转到main画面,并且不再回到start页面,一次设置,不再重复设置,也不用人工点击按钮了。


补充一下,由于博客后台的代码是html,博客内容的一些字符可能会冲突,造成最终的文字与实际代码不一致,后面几天整理好后会把代码截图附上,程序也放入网盘。

posted @ 2021-03-10 20:12  来自金沙江的小鱼  阅读(430)  评论(0编辑  收藏  举报