2008-04-28

VB ~ 每秒抓 BUFF 的資料做曲線圖


問題:


我想用 TIMER 每秒抓 BUFF 資料五百筆來畫出曲線圖 (像心電圖一樣讓曲線一直往左移動),
時間為 X 軸,收到的資料為 Y 軸,請問要怎麼做才能讓曲線向左移動?


回答:

一般的作法就是在 PictureBox 裡面再用 PictureBox,外面的 PictureBox 當作固定的顯示範圍,就好比是儀器的顯示幕,而裡面的 PictureBox 才是繪圖板,這樣你就可以控制內部 PictureBox 的位置 (PictureBox.Left) 來作左移的效果。

內 部 PictureBox 的寬度是考量的重點,必須配合 Timer 的時間間隔、三分鐘的資料以及 X 軸的單位長度來設定。譬如說每秒抓 500 點的資料,三分鐘就有 90,000 點資料,但是 PictureBox.Width 好像不能設得這麼大,顯然用一個 PictureBox 是不夠儲存三分鐘的資料。所以如果一個 PictureBox 儲存 30,000 點資料,就需要三個 PictureBox,也就是說用三個 PictureBox 左右頭尾相接來畫三分鐘的資料。

接著要讓曲線可以自動向左移動,以前面的例子來說,就是在 Timer 的事件中移動這三個 PictureBox,每秒各移動 500 點。另外你必須用一個水平捲軸來控制使用者的捲動,但是這裡你會發現一個問題,如果某一時間三分鐘的資料頭在第一個 PictureBox 的第一點,而資料尾在第三個 PictureBox 的最後一點,那麼下一秒必須捨棄第一個 PictureBox 的前 500 點,然後把最新的 500 點資料畫在最右側,但是第三個 PictureBox 已經畫滿了,而第一個 PictureBox 仍然必須保留在最左側以備查看,所以事實上需要用第四個 PictureBox 來處理這個狀況。在第一個 PictureBox 的資料完全被捨棄後,就要把它調到最右側變成第四個來承接新進的資料。

基本上就是用這樣的方式來循環控制,僅提供你程式寫作的方法,我想程式本身還是要靠自己去寫去試,這樣將來你才有能力知道如何去調整加強它的功能。

Access 裡用 MID 切割中英文的問題


問題:


我在 ACCESS 裡面對一個文字檔用 MID 切割資料並且要存入 Table 中,但是這個文字檔是中英文混雜的,例如其中一行資料是

ABCDEFG中文描述1234567台灣BABYG股份有限公司EXAMPLE

我想要切割成:

ABCDEFG ==> 欄位一 ( 寬度 7 bytes )
中文描述 ==> 欄位二 ( 寬度 8 bytes )
1234567 ==>欄位三 ( 寬度 7 bytes )
台灣BABYG股份有限公司 ==> 欄位四 ( 寬度 21 bytes )
EXAMPLE ==> 欄位五

但是問題發生了,以 "台灣BABYG股份有限公司" 這個部份來看,因為中文字是 double bytes,所以它在文字檔的位置應該是在 23 (7 + 8 + 7 + 1),寬度 21,也就是說應該用 MID(23,21) 來切取,但實際切取的結果卻是 "BYG股份有限公司EXAMPLE",所以變成要用 MID(19.13) 才會正確。MID 函數似乎把 double bytes 的中文算成 single byte,讓我在讀取大量不規則中英文混合的資料上有很大的困擾,不知道有沒有什麼解決之道。

請求協助,謝謝!


回答:

首先必須確定文字檔內的資料欄位都是固定寬度,在使用傳統的 ASCII Code 時,英數字為 1 byte,中文為 2 bytes,但若使用 Unicode,中英文皆為 2 bytes。

在 VBA 程式裡是以 Unicode 處理字串,Mid 函數是以字元的角度來切割字串,不管字元是用 1 個或 2 個 byte 儲存,MidB 函數才是用 byte 來切割字串。

所以你的文字檔和程式的處理方式必須要配合,先弄清楚你的文字檔是用 ASCII Code 還是 Unicode 儲存,如果是 ASCII Code,在讀入整列資料後,要用MidB 函數來切割欄位。

VB 6.0 作業不會打請求程式碼


問題:


輸入四個任意數並且求其最大和最小值,請求給予程式碼。
另外應該要用什麼樣的屬性視窗,希望越詳細越好。

謝謝~~


回答:

Dim i
Dim Result As String
Dim Num, Max, Min As Variant

' 輸入四個任意數並儲存最大和最小值
i = 1
Do While i <= 4
 Num = InputBox("請輸入第 " & Cstr(i) & " 個數")

 If IsNumeric(Num) Then
  If i = 1 Then
   Max = Num
   Min = Num
  ElseIf Num > Max
   Max = Num
  ElseIf Num <>
   Min = Num
  End If

  If Result <> "" Then Result = Result & ", "
  Result = Result & Cstr(Num)
  i = i + 1
 End If
Loop

' 輸出結果
Result = Result & " 四個數之最大值為 " & Cstr (Max) & ", 最小值為 " & Cstr(Min)
MsgBox Result


P.S.使用一般的視窗就可以,在視窗中加一個命令鍵,並把上面的程式複製到這個命令鍵的 Click 事件程序中。

如何將產品依數量遞減排序?


問題:


我有三個 CheckBox,分別為三種產品的核取選項,勾選時會自動累計該產品數量,按 CommandButton 後會將三種產品依數量遞減排序,並顯示於 Label 上。

Ex: 產品 A = 5, 產品 B = 4, 產品 C = 3

請問程式應該怎麼寫?


回答:

假設產品名稱及數量存放在以下陣列變數裡:
Dim ProdName(2) As String
Dim ProdQty(2) As Long

請在 CommandButton 的 Click 事件程序裡加入以下程式碼:

Private Sub Command1_Click()
 Dim ProdRank(2) As Integer, TmpRank As Integer
 Dim i, j As Integer

 ' ProdRank 存放的是產品的索引位置,一開始設定它們的數量排名順序和索引位置相同
 For i = 0 to 2
  ProdRank(i) = i
 Next

 ' 再依照產品實際的數量逐一調整它們的順序
 For i = 0 to 1
  For j = i 1 To 2
   If ProdQty(ProdRank(i)) <>
    TmpRank = ProdRank(i)
    ProdRank(i) = ProdRank(j)
    ProdRank(j) = TmpRank
   End If
  Next
 Next

 ' 將排序結果以 Label1 顯示
 Label1 = ""
 For i = 0 to 2
  Label1 = Label1 & ProdName(ProdRank(i)) & " = " & Cstr(ProdQty(ProdRank(i))) & vbCrlf
 Next
End Sub