轉(zhuǎn))vb拾遺*3(2
30.關(guān)于版本號(hào)
如果程序需要給別人使用,一定要管理好版本號(hào),否則這臺(tái)機(jī)是這個(gè)版本,那臺(tái)機(jī)是那個(gè)版本,會(huì)亂套的,
版本號(hào)由四個(gè)數(shù)字組成,但VB6里的版本號(hào)只能設(shè)置3個(gè)數(shù)字,
分別為主版本、次版本、修正,
在菜單:工程--屬性,“生成”屬性頁可以看到版本,
如果勾選上“自動(dòng)升級(jí)”,則每次編譯新程序時(shí),會(huì)將“修正”值加一。
每次編譯發(fā)布時(shí),在文檔里記錄好這次編譯的版本號(hào)、編譯時(shí)間、以及修改的地方,但很多程序員都不喜歡寫文檔,而且寫文檔攜帶也麻煩,如果沒有帶文檔也就很麻煩了,
那可以將版本號(hào)用年月日來標(biāo)志,
比如版本是:2009.1026.0.2052
表示是2009年10月26日20點(diǎn)52分編譯的,
而修改的內(nèi)容可以放到版本的備注信息里填寫,
版本號(hào)下面的版本信息,類型選擇“注釋”,輸入備注值,
比如備注填寫:
2009.1026.2052:修改了字段aaa
2009.1026.1052:刪除了表bbb
2009.826.1052:增加了表ccc
備注簡要填寫就行。
當(dāng)然,現(xiàn)在很多成熟的軟件都提供自動(dòng)更新功能,
程序自動(dòng)檢測新版本就可以更新了。
如果是信息系統(tǒng),有數(shù)據(jù)庫服務(wù)器(MySql、MsSql、Oracle等),那可以將新程序通過上傳工具上傳到數(shù)據(jù)庫,
客戶機(jī)運(yùn)行程序就檢測版本號(hào),有新版本就從數(shù)據(jù)庫里下載最新版本就行了。
如果不是信息系統(tǒng),或者是桌面版數(shù)據(jù)庫,那可以通過HTTP或者Socket的方式,這兩種方式都需要另建升級(jí)服務(wù)器,比較麻煩。
一般工廠里的信息系統(tǒng),一般都是內(nèi)部使用的,所以維護(hù)版本號(hào)時(shí),能將每臺(tái)客戶機(jī)的版本號(hào)上報(bào)給服務(wù)器,管理人員看一下各客戶機(jī)的版本,就知道哪些沒有更新版本了,即使是自動(dòng)更新,用戶可能會(huì)取消更新的,除非不更新就不給運(yùn)行程序,
但有時(shí)用戶是一天24小時(shí)運(yùn)行著程序的,不能及時(shí)更新程序,
所以知道每臺(tái)客戶機(jī)的版本號(hào),是否是最新版本還是有必要的。
說起這個(gè)一天24小時(shí)運(yùn)行的程序,就想起什么時(shí)候去檢測版本號(hào),一般打開程序時(shí)就會(huì)檢測,但用戶有時(shí)24小時(shí)開著,不關(guān)程序,
所以需要定時(shí)檢測版本,如果版本需要更新就檢查。
如果工程是VSS管理,那編譯之前需要將工程文件(vbp)簽出,
這樣"自動(dòng)升級(jí)版本號(hào)"時(shí),版本號(hào)的修正值才能保存到工程文件里,
版本號(hào)信息是保存在vbp文件里的, 用記事本打開vbp文件就可以看到.
31.工程之間文件互相復(fù)制的問題
很多時(shí)候,需要從別的工程里的窗體復(fù)制到自己的工程里,
但復(fù)制過來后,發(fā)現(xiàn)打開窗體就出錯(cuò),
要復(fù)制窗體,最好在原來的工程里將窗體另存為到新工程的目錄,這樣另存為就可以更改文件名,如果不這樣,而是直接復(fù)制文件過來,然后更改文件名,那如果窗體對應(yīng)有frx文件,那窗體文件(frm)會(huì)找不到frx文件,導(dǎo)致窗體打開出錯(cuò)。
另存為時(shí),會(huì)將frm文件里引用frx文件的地方也重命名的。
另外,如果窗體里有用戶控件時(shí),要特別注意,
因?yàn)閒rm文件是通過:“工程名.用戶控件名”的方式引用用戶控件的,如果新工程與舊工程的工程名不一樣,那會(huì)找不到用戶控件,打開窗體會(huì)出錯(cuò)的,最好先將舊工程另存為到一個(gè)臨時(shí)工程里,工程名字與新工程名字一樣,之后再將窗體另存過去,最后不要保存舊工程就行了。
33.單選框與復(fù)選框的區(qū)別
====================================
在界面上放一個(gè)單選框和一個(gè)復(fù)選框,名字依次為:Check1、Option1
Form_Load里寫如下代碼:
Private Sub Form_Load()
MsgBox Check1.Value
MsgBox Option1.Value
MsgBox TypeName(Check1.Value)
MsgBox TypeName(Option1.Value)
End Sub
發(fā)現(xiàn)復(fù)選框的值是0,而單選框的值是false
復(fù)選框value屬性的類型是 Integer
單選框value屬性的類型是 Boolean
一般我編寫程序時(shí),只關(guān)心是否選中:要么選中,要么沒選中,
象C#等語言里,單選框和復(fù)選框都有Checked屬性,都是布爾型,
但VB是個(gè)例外,VB沒有Checked屬性,只能通過Value屬性來獲取是否選中,而單選框和復(fù)選框的Value屬性類型是不一樣的,
復(fù)選框不能當(dāng)成Boolean型處理,那些象我一樣第一次用VB的人要特別注意。
復(fù)選框三個(gè)狀態(tài):選中、未選中、部分選中
第三個(gè)狀態(tài)“部分選中”只見過很少的地方用,
比如文件夾屬性的那個(gè)“只讀”復(fù)選框,還有就是樹型控件里標(biāo)志子節(jié)點(diǎn)部分選中,做權(quán)限控制時(shí)經(jīng)常用的,瑞星殺毒軟件選擇殺毒文件夾也是三個(gè)狀態(tài)。
34.數(shù)學(xué)分配的問題
====================================
舉個(gè)例子,有一百斤大米,要平分給3個(gè)人,該怎么分?要求必須全部分完,每個(gè)人分得的數(shù)量合計(jì)要等于100, 保留兩位小數(shù)。
如果只是簡單的數(shù)學(xué)運(yùn)算:Round(100 / 3, 2) = 33.33
那每個(gè)人都分得33.33公斤,總和是99.99斤,還有0.01公斤沒分完。
如果是7個(gè)人分,那每個(gè)人分得 round(100/7,2) = 14.29
那每個(gè)人分得14.29公斤,總和=14.29*7=100.03
多出了0.03公斤,
所以這樣簡單的按比例分配不符合要求。比如發(fā)票與入庫單核銷,要求入庫單按數(shù)量比例分配發(fā)票金額,而入庫單金額合計(jì)必須等于發(fā)票金額,一分都不能差。
其實(shí)這里可以采用余數(shù)比例分配法,
第一個(gè)人分時(shí),用:總數(shù) * 所占比例
第二個(gè)人分時(shí),用:剩余未分配數(shù) * 所占比例
第三個(gè)人分時(shí),用:剩余未分配數(shù) * 所占比例
.
.
.
最后一個(gè)人分時(shí),就是等于 剩余未分配數(shù) 就行了,
這樣可以做到盡量的公平,而且保證絕對能分完,不多也不少。
按七個(gè)人分的代碼:
Dim all As Double, i As Long
all = 100
For i = 1 To 7
Dim n As Double
n = Round(1 / (7 - i + 1) * all, 2)
all = all - n
Print n
Next i
各人依次分得的數(shù)為:
14.29、14.29、14.28、14.29、14.28、14.29、14.28
總和 = 14.29+14.29+14.28+14.29+14.28+14.29+14.28 = 100
不多不少,剛好100
上面的代碼要看到結(jié)果,需要設(shè)置窗體屬性 AutoRedraw 為 True
AutoRedraw 是自動(dòng)重繪。
如果你不想設(shè)置 AutoRedraw 為True,設(shè)置AutoRedraw為False時(shí),那就得將 Print語句放到 Paint 事件里:
Paint事件由Windows的窗口管理器自動(dòng)調(diào)用與維護(hù),
Private Sub Form_Paint()
Dim all As Double, i As Long
all = 100
For i = 1 To 7
Dim n As Double
n = Round(1 / (7 - i + 1) * all, 2)
all = all - n
Print n
Next i
End Sub
35.層的設(shè)計(jì)
很多復(fù)雜的系統(tǒng),功能需求相當(dāng)?shù)亩?,如果沒有分層設(shè)計(jì),所有代碼交織在一起,象一團(tuán)麻一樣,那無論是開發(fā)還是維護(hù)還是使用,都是一種災(zāi)難。而且分層設(shè)計(jì)方便分工合作。
比如曾經(jīng)用ASP/VBScript做網(wǎng)站時(shí),以前的做法就是先等美工做出頁面,客戶認(rèn)可了,我們再往頁面里填代碼。后來我采用分層的方式,抽一層業(yè)務(wù)層出來,專門處理業(yè)務(wù)和數(shù)據(jù)。美工做頁面時(shí),我就寫業(yè)務(wù)層,美工頁面做完了,我的業(yè)務(wù)層也寫完了,然后把頁面和業(yè)務(wù)層合并起來就完成了。
舉個(gè)例子,我參與的一個(gè)C/S系統(tǒng),下面是這個(gè)系統(tǒng)某模塊里某個(gè)功能的類里所有的方法:
Public Function zq_qxx_Insert(znid As String, Qyid As String, Qh As Long, qlxid As Long...
Public Function zq_qxx_update(id As Long, qlxid As Long, pzid As Long, zqid As Long
Public Function zq_qxx_delete(qid As Long) As Boolean '刪除
Public Function zq_qxx_ZuoFei(qid As Long) As Boolean '作廢
Public Function zq_qxx_HuiFu(qid As Long) As Boolean '恢復(fù)
Public Function zq_qxx_view(znid As String, swhere As String) As Recordset '查詢視圖
Public Function IsStateDap(pLotId As Long) As Boolean '是否是安排狀態(tài)
Public Function GetMaxQianHao(ByVal Qyid As String) As String '獲取最大號(hào)
Public Function jc_Getzninfo(
Public Function jc_Rows(title As String, ParamArray args()) As Variant
Public Function jc_qyidIsLastLevel(Qyid As String) As Boolean
Public Function jc_ZheNongXinXi(znid As String) As Variant
Public Function jc_QyZn(ByVal Qyid As String, Optional pWhere As String = "") As Recordset
Public Function LoadGlTj(ByVal GlTj As String, Tj_ListView As ListView) As Boolean
Public Function LoadTree(ByVal MyTree As TreeView, ByVal MyIcon As ImageList) As Boolean
Public Function GetQXxLb(rs As Recordset, VsZnXx As VSFlexGrid, RecordCountList As Label,
38.導(dǎo)出Excel單元格合并的問題
要導(dǎo)出Excel也能實(shí)現(xiàn)表頭單元格合并,有兩種處理方式,
方法一:
通過相鄰單元格內(nèi)容相同來合并,這種只適用于表頭合并。
VSFlexGrid就是通過這種方式來合并的,所以導(dǎo)出Excel后也
可以通過這種方式來合并。
先將數(shù)據(jù)按單元格導(dǎo)出到Excel,然后再合并單元格,
完整代碼如下:
Public Sub ExportExcel(pVS As VSFlexGrid, sTitle As String, Optional sHead As String = "", Optional sFoot As String = "", Optional strNums As String = "")
Dim xlApp, xlSheet
Dim i As Long, j As Long
'On Error Resume Next
Set xlApp = CreateObject("Excel.application")
If xlApp Is Nothing Then
Exit Sub
End If
xlApp.Visible = False
Me.MousePointer = vbHourglass
xlApp.Workbooks.Add
Set xlSheet = xlApp.ActiveWorkBook.Sheets(1)
Dim dataRow As Long
Dim xlrow As Long
xlrow = 1
'計(jì)算表格列數(shù)
Dim xlColsCount As Long
For j = 1 To pVS.Cols
If Not pVS.ColHidden(j - 1) Then
xlColsCount = xlColsCount + 1
End If
Next j
'填充標(biāo)題
xlSheet.cells(xlrow, 1).Value = sTitle
xlSheet.Range(xlSheet.cells(xlrow, 1), xlSheet.cells(xlrow, xlColsCount)).Select
xlApp.Selection.HorizontalAlignment = 3
xlApp.Selection.MergeCells = True
xlrow = xlrow + 1
'添加小標(biāo)題
If (sHead <> "") Then
xlSheet.cells(xlrow, 1).Value = sHead
xlSheet.Range(xlSheet.cells(xlrow, 1), xlSheet.cells(xlrow, xlColsCount)).Select
xlApp.Selection.MergeCells = True
xlrow = xlrow + 1
End If
'設(shè)置文本列
Dim sStrs
Dim nStr As Long
If (strNums <> "") Then
sStrs = Split(strNums, ",")
For i = 0 To UBound(sStrs)
nStr = CLng(sStrs(i))
xlSheet.Range(xlSheet.cells(xlrow + pVS.FixedRows, nStr), xlSheet.cells(vs.Rows + xlrow + pVS.FixedRows, nStr)).Select
xlApp.Selection.NumberFormatLocal = "@"
Next
End If
dataRow = xlrow
'填充數(shù)據(jù)
For i = 1 To pVS.Rows
Dim xlcol As Long xlcol = 0 For j = 1 To pVS.Cols If Not pVS.ColHidden(j - 1) Then xlcol = xlcol + 1 xlSheet.cells(xlrow, xlcol).Value = pVS.TextMatrix((i - 1), (j - 1)) '加上“'”號(hào)則可以解決上面savegrid中銀行賬號(hào)的導(dǎo)出問題。 End If Next j xlrow = xlrow + 1 DoEvents Next i '填充表尾 If (sFoot <> "") Then xlSheet.cells(xlrow, 1) = sFoot xlSheet.Range(xlSheet.cells(xlrow, 1), xlSheet.cells(xlrow, xlColsCount)).Select xlApp.Selection.MergeCells = True xlrow = xlrow + 1 End If '合并表頭 '--------行合并 Dim prevText As String, sameStart As Long, sCell As String For i = dataRow To dataRow + pVS.FixedRows - 1 prevText = "" sameStart = 1 For j = 1 To xlColsCount
sCell = xlSheet.cells(i, j).Value If (sCell <> prevText) Then If (j > 1) Then xlSheet.Range(xlSheet.cells(i, sameStart), xlSheet.cells(i, j - 1)).Select xlApp.Selection.MergeCells = True 'xlSheet.cells(i, sameStart).Value = prevText End If sameStart = j prevText = sCell Else xlSheet.cells(i, j).Value = "" If (j = xlColsCount) Then xlSheet.Range(xlSheet.cells(i, sameStart), xlSheet.cells(i, j)).Select xlApp.Selection.MergeCells = True End If 'sameStart = sameStart + 1 End If Next j Next i '--------列合并 If pVS.FixedRows > 1 Then For i = 1 To xlColsCount prevText = "" sameStart = dataRow For j = dataRow To dataRow + pVS.FixedRows - 1 sCell = xlSheet.cells(j, i).Value If (sCell <> prevText) Then If (j > dataRow) Then If prevText <> "" Then
xlSheet.Range(xlSheet.cells(sameStart, i), xlSheet.cells(j - 1, i)).Select xlApp.Selection.MergeCells = True End If 'xlSheet.cells(i, sameStart).Value = prevText End If sameStart = j prevText = sCell Else xlSheet.cells(j, i).Value = "" If (j = dataRow + pVS.FixedRows - 1) Then If prevText <> "" Then xlSheet.Range(xlSheet.cells(sameStart, i), xlSheet.cells(j, i)).Select xlApp.Selection.MergeCells = True End If End If 'sameStart = sameStart + 1 End If Next j Next i End If '設(shè)置表頭居中 xlSheet.Range(xlSheet.cells(dataRow, 1), xlSheet.cells(dataRow + pVS.FixedRows - 1, xlColsCount)).Select xlApp.Selection.HorizontalAlignment = 3 '自動(dòng)列寬列高 xlSheet.Columns.AutoFit '調(diào)整行高 For i = 1 To vs.Rows xlSheet.Rows(i).RowHeight = xlSheet.Rows(i).RowHeight + 6 '自動(dòng)大小后上下無邊距,需要增加高度,要不太擠。 Next i
'合并單元格 For i = 1 To vs.FixedRows 'for j = 1 to Next i Me.MousePointer = vbDefault xlApp.Visible = True Set xlApp = Nothing |