最近在学习金蝶K3老单二次开发, 那么这篇文章是将是新手绕不开的关键步骤
原来看了一本书, 还写了好多笔记, 然而并没有实践; https://blog.csdn.net/wacolly/article/details/78631769
现在理解的VB就是 : 在对象
发生某个事件
时, 执行了一些代码
, 然后实现了某些
功能.
举个最简单的例子: 新建一个程序(工程), 添加2个窗体:form1 和 form2, 在form1 中添加一个 command 按钮. 在command 对象
产生click 事件
的时候, 执行了form2.show 代码
, 就实现了在窗体1中点击按钮打开了窗体2
这个功能.
下载V6+SP6完整版安装包下载, 大小 ≈ 300M
提取码:回复可见
一、数据库操作函数
定义一个函数
Public Function ExecuteSQL(byval SQLcommad, byref MsgString)
参数1和参数2的区别参考文末的Byval和Byref的区别
使用adodb连接需要在工程
->引用
->Micsoft A D O x.x Library
'***************************************************
'数据库连接字符串, 可以写成一行:Public Const MyConnectString as String =""
'***************************************************
Public Function MyConnectString() As String
MyConnectString = "provider=sqloledb.1;persist security info = true; user id = 用户名; password = 密码;initial catalog = 数据库; data source = 服务器(name or ip)"
End Function
'***************************************************
'数据库操作函数
'***************************************************
Public Function ExecuteSQL(ByVal SQLcommand As String, MsgString As String) As ADODB.Recordset
'定义一个数据库连接
Dim MyCnn As ADODB.Connection
'定义一个数据库表对象
Dim MyRecordset As ADODB.Recordset
'定义一个数组
Dim sTokens() As String
'出现错误时跳转到ExecuteSQL_Error处执行
sTokens = Split(SQLcommand) 'SQLcommand为传入的sql语句, 用split方法对其进行分拆
Set MyCnn = New ADODB.Connection
'连接数据库
MyCnn.Open MyConnectString
If InStr("INSERT,DELETE,UPDATE", UCase(sTokens(0))) Then 'UCase 小写转大写
MyCnn.Execute SQLcommand
MsgString = sTokens(0) & "Query successful"
Else
Set MyRecordset = New ADODB.Recordset '创建结果集对象
MyRecordset.Open Trim(SQLcommand), MyCnn, adOpenKeyset, adLockOptimistic '返回查询结果
Set ExecuteSQL = MyRecordset '返回记录集对象
MsgString = "共查询到" & MyRecordset.RecordCount & "条记录"
End If
ExecuteSQL_Exit:
Set MyRecordset = Nothing '清空数据集对象
Set MyCnn = Nothing '中断连接
Exit Function
ExecuteSQL_Error:
MsgString = "查询错误:" & Err.Description
Resume ExecuteSQL_Exit
End Function
函数的调用及主要方法
假设在点击事件中执行
Private Sub cmdOK_Click()
Dim MySQL As String '传入参数1, 存储sql语句
Dim MyRec As ADODB.Recordset '存储sql操作的结果集
Dim MyMsgString As String '传入参数2, 可以为空
Dim str as String '存储一个比较值
str = txtUserName.Text '假设界面上有一个txtUserName文本框
MySQL = "SELECT * FROM TABLE_NAME WHERE COLUMN = '" & str & "'"
Set MyRec = ExecuteSQL(MySQL, MyMsgString) '返回sql操作结果集
返回的结果集MyRec有以下方法: (不完整, 待完善)
MyRec.EOF
一般用于判断是否查询到记录, 详细说明参考文末附件
MyRec.Fields
定位到某一列, 例如:
x = MyRec.Fields(0) 表示取记录的第1个字段的值赋值给变量x
创建一条记录, 例如
MyRec.AddNew
MyRec.Fields(0) = 1 表示将结果集第1个字段的值置为1
MyRec.Fields(0).Type 获取值的类型; 如: adDBDate日期类型
MyRec.Update
MyRec.Close
MyRec.MoveNext
移动到数据集的下一条记录, 常使用在循环中
二、VB知识点收集
.EOF和.BOF的用法
- BOF 指示当前记录位置位于 Recordset 对象的第一个记录之前。
- EOF 指示当前记录位置位于 Recordset 对象的最后一个记录之后。
- BOF 和 EOF 属性返回布尔型值。
说明:
使用 BOF 和 EOF 属性可确定 Recordset 对象是否包含记录,或者从一个记录移动到另一个记录时是否超出 Recordset 对象的限制。 如果当前记录位于第一个记录之前,BOF 属性将返回 True (-1),如果当前记录为第一个记录或位于其后则将返回 False (0)。 如果当前记录位于 Recordset 对象的最后一个记录之后 EOF 属性将返回 True,而当前记录为 Recordset 对象的最后一个记录或位于其前,则将返回 False。 如果 BOF 或 EOF 属性为 True,则没有当前记录。 如果打开没有记录的 Recordset 对象,BOF 和 EOF 属性将设置为 True,而 Recordset 对象的 RecordCount 属性设置为零。打开至少包含一条记录的 Recordset 对象时,第一条记录为当前记录,而 BOF 和 EOF 属性为 False。 如果删除 Recordset 对象中保留的最后记录,BOF 和 EOF 属性将保持 False,直到重新安排当前记录。
ByVal 与 ByRef 的区别
简而言之,ByVal 和 ByRef 的区别在于参数源是否可以被函数修改,前者是不能被修改的, 而后者(默认方式)是可以被修改的。
InStr语法
InStr([start], string1, string2, [compare])
InStr函数的返回值是第二个参数在第一个参数中第一次出现的位置。
InStr 函数的语法具有下面的参数:
- 1,start 可选。数值表达式,用于设置每次搜索的开始位置。如果省略,将从第一个字符的位置开始搜索。如果 start 包含 Null,则会出现错误。如果已指定 compare,则必须要有 start 参数。
- 2,string1 必选。接受搜索的字符串表达式。
- 3,string2 必选。要搜索的字符串表达式。
- 4,compare 可选。指示在计算子字符串时使用的比较类型的数值。如果省略,将执行二进制比较。
while与DO while区别
退出不同、执行不同、优先不同。
- 一、退出不同
1、while...wend:不可以中途通过代码Exit Do进行退出。
2、DO while...loop:可以中途通过代码Exit Do进行退出。
- 二、执行不同
1、while...wend:至少会执行一次循环体。
2、DO while...loop:可能会出现一次都不执行循环体的情况。
- 三、优先不同
1、while...wend:优先执行循环体,再判断执行条件是否符合要求。
2、DO while...loop:优先判断执行条件是否符合要求,再执行循环体。
窗体
MDI窗体和SDI窗体
- MDI窗体: 一个工程只能有一个MDI窗体, 它里面可以有多个子窗体(MDICHILD = True); 子窗体不能以模态窗体打开
- 普通(SDI)窗体: 非子窗体可以在
工具
->菜单编辑器
进行菜单编辑
窗体的打开方式: 模态和非模态
- 模态窗体: 打开模态窗体以后不能操作其他窗体, 建立在模态窗体之上的必须为模态窗体 form.show 1
- 非模态窗体: 自由的 form.show 0
MSFlexGrid控件的属性与方法
工程
->部件
->Microsoft FlexGrid Control 6.0
with MSFlexGrid
.Cols = 12 '列数
.TextMatrix(row,col) = "编号" '给单元格填充内容 (注意索引从0开始)
.FixedRows = 1 '固定表头, 第1行
.FixedCols = 2 '固定表列, 前2列
.ColAlignment(col_index) = 0 '某列的对齐方式, ????
'单元格格式化↓
.FillStyle = flexFillRepeat '允许1次对1个以上的单元格进行格式化, 缺省默认值为flexFillSingle
'范围选择, (0行0列 ~to~ 1行11列)
.Row = 0
.Col = 0
.RowSel = 1
.ColSel = 11
'对所选范围的所有单元格设置格式
.cellFontBold = True
.cellFontItalic = True
.cellFontUnderline = True
.cellAlignment = 0 'to 9
'0 : flexAlignLeftTop
'1 : flexAlignLeftCenter
'2 : flexAlignLeftBottom
'3 : flexAlignCenterTop
'4 : flexAlignCenterCenter
'5 : flexAlignCenterBottom
'6 : flexAlignRightTop
'7 : flexAlignRightCenter
'8 : flexAlignRightBottom
'9 : flexAlignGeneral 一般对齐:字符串LeftCenter,数字RightCenter
.cellFontName = ""
.cellFontSize = 14
.cellForeColor = "red"
.cellBackColor = "blue"
.ColWidth(col_index) = 1000 '将第n+1列宽度设置为1000像素
.Rows '获取表格行数; 赋值语句.Rows = 1可以设置表格的行数
窗体或控件的尺寸
'窗体状态
Me.WindowState =
vbMinimized: 最小化
vbMaximized: 最大化
vbNormal : 还原正常
'窗体尺寸
Me.ScaleHeight = 1000 '除去边框的内高
Me.ScaleWidth = 1000 '除去边框的内宽
'控件的相关属性
label.Top = '容器内的上边距
label.Left = '容器内的左边距
label.Height = '自身高度
label.Width = '自身宽度
变量的作用域
vb中在窗体模块声明的全局变量与在标准模中声明的全局变量作用域相同吗?
作用域相同,但是就是引用的时候有点不一样。比如在form1的通用段中用public声明的全局变量,public a%,如果要在form1中的其他过程或函数中引用的时候,直接引用a,可是如果在其他窗体或标准模块的代码中引用a的时候要加上form1的限制,就要写成form1.a的形式。
如果实在标准模块中用public声明的全局变量,只要在本工程内部不管什么代码中是那就直接引用就可以了。
三、一些错误的解决方法
实时错误‘94’无效使用null值
问题产生在: 从 数据库取数 赋值给 text1.text文本框 的时候,
由于数据库允许null值, 但text1.text不接受null值(可以接受空字符串), 所以需要在后面连接一个空字符串 &""
就可以了