返回列表 上一主題 發帖

[分享] 盤中 DDE 存檔與 VBA 的實際應用範例

[分享] 盤中 DDE 存檔與 VBA 的實際應用範例

貼上盤中 DDE 存檔與 VBA 的實際應用範例,供大家參考應用 (祈能普渡眾生)
這也是一般人在實務運用上常碰到的問題盲點,與其苦思困惑不知如何起筆
不如分享所知使人豁然頓悟。
希望大家以後都能成為高人,並祈指導指正!
盤中 DDE 存檔的實際應用範例.rar (1.11 KB)

我差點忘了與我擁有小學生等級的同學們是無法下載附件的,
所以我又將它直接貼了出來,方便大家閱覽。
  1. ' 盤中 DDE 存檔的實際應用範例

  2. Option Explicit

  3. Dim actEnabled As Boolean
  4. Dim index As Single

  5. Private Sub Workbook_Open()
  6.     If (Sheets("工作表1").Range("AA1").Value = "") Then Sheets("工作表1").Range("AA1").Value = "08:45:00"   ' 假設AA1欄位為空白,則寫入開盤起始時間
  7.     If (Sheets("工作表1").Range("AA2").Value = "") Then Sheets("工作表1").Range("AA2").Value = "13:45:59"   ' AA2欄位亦同。(此兩欄紀錄起始終止時間)
  8.     If (Sheets("工作表1").Range("AA3").Value = "") Then Sheets("工作表1").Range("AA3").Value = 0            ' 紀錄最後資料匯入之列號 (Rows)。
  9.     If (Sheets("工作表1").Range("AA4").Value = "") Then Sheets("工作表1").Range("AA4").Value = "00:00:10"   ' 紀錄資料匯入相隔時間,如每隔十秒寫入一次。

  10.     If (TimeValue(Now) > Sheets("工作表1").Range("AA2").Value) Then       ' 如果目前時間業已超過AA2的時段,則呼叫.......
  11.         Call stopProcedure
  12.     Else                                                                  ' 反之,則呼叫.......
  13.         Call startProcedure
  14.     End If
  15. End Sub

  16. Private Sub Workbook_BeforeClose(Cancel As Boolean)
  17.     On Error Resume Next
  18.     Call actStop
  19. End Sub


  20. Private Sub startProcedure()       ' 保留作為控制項之應用程序,如按鈕之巨集應用等。
  21.     Call actStart
  22. End Sub

  23. Private Sub stopProcedure()        ' 保留作為控制項之應用程序,如按鈕之巨集應用等。
  24.    Call actStop
  25. End Sub

  26. Sub Starter()
  27.     If (actEnabled = True And TimeValue(Now) >= Sheets("工作表1").Range("AA1").Value And TimeValue(Now) <= Sheets("工作表1").Range("AA2").Value) Then
  28.         index = Sheets("工作表1").Range("AA3").Value

  29.         If (Index = 0) Then Call newTitle  '假設newTitle程序(由使用者自行定義)是將第一列的資料抬頭名稱寫入到工作表2。 如:日期、時間、R1C5的對應欄位資料等。

  30.         Sheets("工作表1").Range("AA3").Value = index + 1       ' 紀錄列號加一。
  31.         Sheets("工作表2").Cells(index + 2, 1).Value = Date
  32.         Sheets("工作表2").Cells(index + 2, 2).Value = TimeValue(Now)
  33.         ' Sheets("工作表2").Cells(index + 2, 3).Value = Sheets("工作表1").Cells(1, 5).Value
  34.         '
  35.         ' 複製從券商DDE匯入之相對應位置資料,如 R1C5 對應的可能是收盤價等等。
  36.         '
  37.     End If
  38. End Sub


  39. Sub onStarter()
  40.     Call Starter
  41.     If actEnabled Then Call actStart
  42. End Sub

  43. Sub actStart()
  44.     actEnabled = True
  45.     Application.OnTime (Now + Sheets("工作表1").Range("AA4").Value), "ThisWorkBook.onStarter"   ' 寫入資料的排程 (目前是每隔十秒寫入一次)
  46. End Sub

  47. Sub actStop()
  48.     actEnabled = False

  49.     On Error Resume Next
  50.     Application.OnTime Now, "ThisWorkBook.onStarter", , False
  51. End Sub
複製代碼

TOP

回復 3# ajagow
這個模組旨在提供你如何在實務上撰寫一個屬於你個人的程式碼範例,
它的確是一組真的程式模組,你只是把對應的欄位加以修飾,再加上你個人的思考模式加以套入組合,
就成了你所需要的完整之程式碼了。
我再把它貼一次,程式碼請複製到 ThisWorkbook 內,直接編譯也無問題的。
  1. ' 盤中 DDE 存檔的實際應用範例

  2. Option Explicit

  3. Dim actEnabled As Boolean
  4. Dim index As Single

  5. Private Sub Workbook_Open()
  6.     If (Sheets("工作表1").Range("AA1").Value = "") Then Sheets("工作表1").Range("AA1").Value = "08:45:00"   ' 假設AA1欄位為空白,則寫入開盤起始時間
  7.     If (Sheets("工作表1").Range("AA2").Value = "") Then Sheets("工作表1").Range("AA2").Value = "13:45:59"   ' AA2欄位亦同。(此兩欄紀錄起始終止時間)
  8.     If (Sheets("工作表1").Range("AA3").Value = "") Then Sheets("工作表1").Range("AA3").Value = 0            ' 紀錄最後資料匯入之列號 (Rows)。
  9.     If (Sheets("工作表1").Range("AA4").Value = "") Then Sheets("工作表1").Range("AA4").Value = "00:00:10"   ' 紀錄資料匯入相隔時間,如每隔十秒寫入一次。

  10.     If (TimeValue(Now) > Sheets("工作表1").Range("AA2").Value) Then       ' 如果目前時間業已超過AA2的時段,則呼叫.......
  11.         Call stopProcedure
  12.     Else                                                                  ' 反之,則呼叫.......
  13.         Call startProcedure
  14.     End If
  15. End Sub

  16. Private Sub Workbook_BeforeClose(Cancel As Boolean)
  17.     On Error Resume Next
  18.     Call actStop
  19. End Sub


  20. Sub startProcedure()       ' 保留作為控制項之應用程序,如按鈕之巨集應用等。
  21.     Call actStart
  22. End Sub

  23. Sub stopProcedure()        ' 保留作為控制項之應用程序,如按鈕之巨集應用等。
  24.    Call actStop
  25. End Sub

  26. Sub nnewTitle()
  27.    ' 套上你欲匯入資料的表頭名稱
  28. End Sub

  29. Sub Starter()
  30.     If (actEnabled = True And TimeValue(Now) >= Sheets("工作表1").Range("AA1").Value And TimeValue(Now) <= Sheets("工作表1").Range("AA2").Value) Then
  31.         index = Sheets("工作表1").Range("AA3").Value

  32.         If (index = 0) Then Call newTitle  '假設newTitle程序(由使用者自行定義)是將第一列的資料抬頭名稱寫入到工作表2。 如:日期、時間、R1C5的對應欄位資料等。

  33.         Sheets("工作表1").Range("AA3").Value = index + 1       ' 紀錄列號加一。
  34.         Sheets("工作表2").Cells(index + 2, 1).Value = Date
  35.         Sheets("工作表2").Cells(index + 2, 2).Value = TimeValue(Now)
  36.         ' Sheets("工作表2").Cells(index + 2, 3).Value = Sheets("工作表1").Cells(1, 5).Value
  37.         '
  38.         ' 複製從券商DDE匯入之相對應位置資料,如 R1C5 對應的可能是收盤價等等。
  39.         '
  40.     End If
  41. End Sub


  42. Sub onStarter()
  43.     Call Starter
  44.     If actEnabled Then Call actStart
  45. End Sub

  46. Sub actStart()
  47.     actEnabled = True
  48.     Application.OnTime (Now + Sheets("工作表1").Range("AA4").Value), "ThisWorkBook.onStarter"   ' 寫入資料的排程 (目前是每隔十秒寫入一次)
  49. End Sub

  50. Sub actStop()
  51.     actEnabled = False

  52.     On Error Resume Next
  53.     Application.OnTime Now, "ThisWorkBook.onStarter", , False
  54. End Sub
複製代碼

TOP

回復 5# Hsieh
謝謝您的指正!
今後我會特別去留意VBA的保留字, 我已將 index 更改成 cIndex (Check Index 之意,可依每個人編碼習慣自行去定義)
真不好意思留下了不好的錯誤示範。

TOP

回復 7# ajagow
對不起!
在範例中 Sub newTitle()  (之前本想由使用者自行加上,但為增進你的瞭解,臨時加入的) 誤打成 Sub nnewTitle() 請你自行更正,
請留意 ThisWorkBook.onStarter,在 ThisWorkBook.onStarter中是有一點 "." 的 (ThisWorkBook + "." +  onStarter),
此意即是 "當設定時段到時即予執行 onStarter此程式段"

Sub onStarter()
    Call Starter
    If actEnabled Then Call actStart
End Sub

onStarter 程式段會去執行 Starter (此程式段負責將從DDE匯入之盤中資訊,實際寫入到你指定編寫的工作表單內),
執行完畢又會到 actStart 的排程。 如此不斷循環作業,直到條件滿足為止。

TOP

回復 9# ajagow
麻煩上傳檔案!

TOP

回復 11# ajagow
欄位的確認非常重要,你的語法我稍加修改了一下,大體上也都不錯,只是時間欄位的認定模糊而已,
我將修改之處用  ' ******** 加以標示出來,方便你瞭解無法執行的原因,下回你就會實際應用了。
附上已執行的範例,以及你的修改後之程式碼 (因你尚無法下載,所以將它貼示出來),你將程式碼複製到 ThisWorkbook 內,而將模組移除掉。
  1. ' 盤中 DDE 存檔的實際應用範例
  2. Option Explicit
  3. Dim actEnabled As Boolean
  4. Dim CIndex As Single

  5. Private Sub Workbook_Open()
  6.     If (Sheets("工作表1").Range("A1").Value = "") Then Sheets("工作表1").Range("A1").Value = "01:11:00"   ' 假設A1欄位為空白,則寫入開盤起始時間
  7.     If (Sheets("工作表1").Range("A2").Value = "") Then Sheets("工作表1").Range("A2").Value = "13:45:59"   ' A2欄位亦同。(此兩欄紀錄起始終止時間)
  8.     If (Sheets("工作表1").Range("A3").Value = "") Then Sheets("工作表1").Range("A3").Value = 0            ' 紀錄最後資料匯入之列號 (Rows)。
  9.     If (Sheets("工作表1").Range("A4").Value = "") Then Sheets("工作表1").Range("A4").Value = "00:00:10"   ' 紀錄資料匯入相隔時間,如每隔十秒寫入一次。

  10.     ' If (TimeValue(Now) > Sheets("工作表1").Range("A2").Value) Then     ' ********  你打算何時開始運作?13:45:59 以後?
  11.     If (TimeValue(Now) > Sheets("工作表1").Range("A1").Value) Then       ' 如果目前時間業已超過A2的時段,則呼叫.......
  12.         ' Call stopProcedure         ' ***** 時間到了,難道你不要執行?
  13.         Call startProcedure
  14.     Else                                                                  ' 反之,則呼叫.......
  15.         Call stopProcedure
  16.         ' Call startProcedure        ' ***** 請問你是要它在 14:00 ~ 01:09 間執行?
  17.     End If
  18. End Sub

  19. Private Sub Workbook_BeforeClose(Cancel As Boolean)
  20.     On Error Resume Next
  21.     Call actStop
  22. End Sub

  23. Sub startProcedure()       ' 保留作為控制項之應用程序,如按鈕之巨集應用等。
  24.     Call actStart
  25. End Sub

  26. Sub stopProcedure()        ' 保留作為控制項之應用程序,如按鈕之巨集應用等。
  27.    Call actStop
  28. End Sub

  29. Sub newTitle()
  30.    ' 套上你欲匯入資料的表頭名稱
  31. End Sub

  32. Sub Starter()
  33.     If (actEnabled = True And TimeValue(Now) >= Sheets("工作表1").Range("A1").Value And TimeValue(Now) <= Sheets("工作表1").Range("A2").Value) Then
  34.         CIndex = Sheets("工作表1").Range("A3").Value

  35.         If (CIndex = 0) Then Call newTitle  '假設newTitle程序(由使用者自行定義)是將第一列的資料抬頭名稱寫入到工作表2。 如:日期、時間、R1C5的對應欄位資料等。

  36.         Sheets("工作表1").Range("A3").Value = CIndex + 1       ' 紀錄列號加一。
  37.         Sheets("工作表2").Cells(CIndex + 2, 1).Value = Date
  38.         Sheets("工作表2").Cells(CIndex + 2, 2).Value = TimeValue(Now)
  39.         ' Sheets("工作表2").Cells(CIndex + 2, 3).Value = Sheets("工作表1").Cells(1, 5).Value
  40.         Sheets("工作表2").Cells(CIndex + 2, 3).Value = Sheets("工作表1").Cells(6, 1).Value         ' 測試, 因今天不賣魚, 你的指定欄位有點..........

  41.         '

  42.         ' 複製從券商DDE匯入之相對應位置資料,如 R1C5 對應的可能是收盤價等等。

  43.         '
  44.         CIndex = Sheets("工作表1").Range("A3").Value      ' ********* 增加部分  (Counter 要加一,否則永遠為零)
  45.     End If
  46. End Sub

  47. Sub onStarter()
  48.     Call Starter
  49.     If actEnabled Then Call actStart
  50. End Sub

  51. Sub actStart()
  52.     actEnabled = True
  53.     ' Application.OnTime (Now + Sheets("工作表2").Range("A4").Value), "ThisWorkBook.onStarter"   ' ***** 工作表 2 的 A4 哪來個時間設定?
  54.     Application.OnTime (Now + Sheets("工作表1").Range("A4").Value), "ThisWorkBook.onStarter"     ' 寫入資料的排程 (目前是每隔十秒寫入一次)
  55. End Sub

  56. Sub actStop()
  57.     actEnabled = False

  58.     On Error Resume Next
  59.     Application.OnTime Now, "ThisWorkBook.onStarter", , False
  60. End Sub
複製代碼
DDE-4-14 盤中 DDE 存檔與 VBA 的實際應用範例.rar (14.01 KB)

TOP

回復 16# ajagow
請您留意看看,在您程式執行的階段是否同時會去執行別支 Excel 程式?
如果有的話,請勿操作別支 Excel,因為它們的執行序可能被干擾到了。

TOP

回復  c_c_lai


    那請較一下,若同時取用不同訊號來源時,要如何規避您所說的錯誤風險呢?
ribbits 發表於 2012-9-9 11:07

非 "不同訊號來源",我指的是盡可能不要在同一時段去
同時執行一支以上帶有VBA程式執行碼的 Excel 檔案。
附上圖片希望能幫助你了解:

你可以在一表單內同時匯入一支以上不同 DDE 訊號來源,這絕對是 OK 的,
但是如果你在同一時段同時執行一支以上類似如此之VBA
執行程式,VBA 程式極有可能會隨時莫名其妙地被中斷 (Interrupt)。
(我個人體驗,屢試不爽)    因此才會如此建議的。

TOP

回復 24# ribbits
端視你程式撰寫的技巧,是可以做到的!

TOP

        靜思自在 : 忘功不忘過,忘怨不忘恩。
返回列表 上一主題