返回列表 上一主題 發帖

儲存不會自動停止,該怎麼改?

本帖最後由 stillfish00 於 2013-8-6 11:35 編輯

回復 3# ahsiek
詢問的問題如下:
1.        AA(工作表)開始後無法自動停止,我設定在ROW33後就停止儲存
結果,在ROW33是停了,但它就跑到ROW2、3,就在那裡繼續作動作。
這是我哪裡寫錯了嗎?
首先你用這取最後一行的行號
endCol = 工作表29.Cells(33, 1).End(xlUp).Row
End(xlUp)相當於按 END+向上鍵,當A1~A33都有值時,這行取到的是1

再來你用

   If ActiveCell.Row > 33 Then End       '限制總列數
    If ActiveCell.Column = 30 Then End       '中途中止   

但是程式中實際ActiveCell卻一直是固定同一格,當然不會終止
而且切換工作表ActiveCell也會變...........


2.        BB(工作表)也是如此,這兩個工作表的錄製是一樣的。所以也是不會自動停下來。
3.        AA(工作表),一旦按下開始動作,若我再去BB(工作表)按下任意鍵,則AA(工作表)和BB(工作表)都不會動了。
4.        AA(工作表),若按下終止鍵,結果連BB(工作表)也跟著不會動了。

基本上我會重寫如下,你可以參考看看:
  1. Private gbStop1 As Boolean
  2. Private gbStop2 As Boolean

  3. Sub ButtonStart1()  'AA工作表開始按鈕
  4.   gbStop1 = False
  5.   With ActiveSheet
  6.     .UsedRange.Offset(3).ClearContents
  7.     SetTimer1 .Name
  8.   End With
  9. End Sub
  10. Sub ButtonStop1()   'AA工作表停止按鈕
  11.   gbStop1 = True
  12. End Sub
  13. Sub ButtonStart2()  'BB工作表開始按鈕
  14.   gbStop2 = False
  15.   With ActiveSheet
  16.     .UsedRange.Offset(3).ClearContents
  17.     SetTimer2 .Name
  18.   End With
  19. End Sub
  20. Sub ButtonStop2()   'BB工作表停止按鈕
  21.   gbStop2 = True
  22. End Sub

  23. '將不同表的排程部分/限制行數/分離出來
  24. Sub SetTimer1(sSheetName As String)
  25.   Const MAX_ROW = 34
  26.   '未達限制行數且沒按停止鈕則排程1秒後再度執行
  27.   If mainFunc(sSheetName) < MAX_ROW And Not gbStop1 Then Application.OnTime Now + TimeValue("00:00:01"), "'SetTimer1 """ & sSheetName & """'"
  28. End Sub

  29. Sub SetTimer2(sSheetName As String)
  30.   Const MAX_ROW = 270
  31.   If mainFunc(sSheetName) < MAX_ROW And Not gbStop2 Then Application.OnTime Now + TimeValue("00:00:01"), "'SetTimer2 """ & sSheetName & """'"
  32. End Sub

  33. Function mainFunc(sSheetName As String) As Long
  34.   Dim i As Long
  35.   
  36.   With Sheets(sSheetName)
  37.     i = .Cells(.Rows.Count, 1).End(xlUp).Row + 1

  38.     '...記錄log
  39.     .Cells(i, "A") = Format(Time, "Hh:Mm:Ss")
  40.     .Cells(i, "J").Resize(, 8).Value = .Cells(3, "B").Resize(, 8).Value
  41.   End With
  42.   
  43.   mainFunc = i  '回傳當前列數
  44. End Function
複製代碼

TOP

回復 9# ahsiek
那SetTimer2中改為  If mainFunc2(sSheetName)
另新增:
  1. Function mainFunc2(sSheetName As String) As Long
  2.   Dim i As Long
  3.   
  4.   With Sheets(sSheetName)
  5.     i = .Cells(.Rows.Count, 1).End(xlUp).Row + 1

  6.     '...記錄log
  7.     .Cells(i, "A") = Format(Time, "Hh:Mm:Ss")
  8.     .Cells(i, "E").Resize(, 3).Value = .Cells(3, "B").Resize(, 3).Value
  9.   End With
  10.   
  11.   mainFunc2 = i  '回傳當前列數
  12. End Function
複製代碼

TOP

回復 13# ahsiek
抱歉了,我也不曉得DDE是否會/如何影響或取消Excel的部分功能,
也有可能是與Excel應用程式資源分配問題,這方面沒有研究過,
手邊也沒相關工具可測試,這問題可能要請教其他版友是否能解惑了。

但一般常見的是藉由工作表的Calculate事件來記錄DDE的值,版上也有類似討論可參考看看。

TOP

回復 16# ahsiek
我很確定F3 & G3的格子都是有數值的,而L4 & M4是複製F3& G3的數值,為什麼還會出現#DIV/0!呢?

我也覺得不會有這情形,你是如何確定"當下"的F3 & G3的格子都是有數值的?
  1. 若真的是因為F3&G3的公式,而導致L4&M4出現#DIV/0!的話,有什麼方法可以讓L4&M4單純儲存數值就好呢?
複製代碼
反過來問,若F3&G3就是#DIV/0!,你要L4&M4儲存什麼數值?

TOP

回復 22# ahsiek
因為原本code中stop的機制,不是立即停止的,而是下次排程的時間到了才去判斷到該變數,不讓它有再下一次的排程。
所以原本設1秒,只要按停止後的一秒內不再重新開始就不會有問題,而現在時間拉長的話就有問題了。。。

可以參考修改如下看看,mainFunc() 不變:
  1. Private gNextRunTime1 As Date
  2. Private gbIsRunning1 As Boolean

  3. Sub ButtonStart1()  '工作表開始按鈕
  4.   '防止多次啟動
  5.   If gbIsRunning1 = True Then
  6.     If MsgBox("已有存在的排程:" & gNextRunTime1 & ",是否取消該排程,重新紀錄?", vbOKCancel) = vbOK Then
  7.       ButtonStop1
  8.     Else
  9.       Exit Sub
  10.     End If
  11.   End If
  12.   
  13.   With ActiveSheet
  14.     .Range("A4:G270").ClearContents
  15.     gbIsRunning1 = True
  16.     SetTimer1 .Name
  17.   End With
  18. End Sub

  19. Sub ButtonStop1()   '工作表停止按鈕
  20.   gbIsRunning1 = False
  21.   
  22.   On Error Resume Next
  23.   '取消下次執行時間
  24.   Application.OnTime gNextRunTime1, "'SetTimer1 """ & ActiveSheet.Name & """'", , False
  25.   On Error GoTo 0
  26. End Sub

  27. Sub SetTimer1(sSheetName As String)
  28.   Const MAX_ROW = 270
  29.   
  30.   gNextRunTime1 = Now + TimeValue("00:00:10")
  31.   Application.OnTime gNextRunTime1, "'SetTimer1 """ & sSheetName & """'"
  32.   
  33.   If mainFunc(sSheetName) >= MAX_ROW Then ButtonStop1 '執行並回傳row
  34. End Sub
複製代碼

TOP

回復 27# ahsiek
根據Application.OnTime ,其參數LatestTime 的說明:
  1. LatestTime 選用 Variant

  2. 可以開始執行程序的最晚時間。例如,假設 LatestTime 設為 EarliestTime + 30,當時間到了 EarliestTime 時,如果由於其他程序正在執行中而使 Microsoft Excel 不處於 [就緒]、[複製]、[剪下] 或 [尋找] 模式,則 Microsoft Excel 會等待 30 秒以完成第一個程序。如果 30 秒內 Microsoft Excel 無法回到 [就緒] 模式,則不會執行此程序。如果省略此引數,Microsoft Excel 會一直等到可以執行該程序為止。
複製代碼
由於省略此引數,Microsoft Excel 會一直等到可以執行該程序為止。
也許是這樣導致你紀錄時間的動作延後,而有你說的"漏了幾秒"的結果,這可能沒辦法解決。。。

但我會建議你試試看,紀錄的巨集用一個Excel應用程式常駐,如果有其他Excel 工作需要處理的話,
另外開一個Excel應用程式(從開始功能表或捷徑開啟excel,不要直接雙擊excel檔案,
使工作管理員可看見兩個Excel.exe處理程序),也許能避免資源衝突問題。

TOP

回復 29# ahsiek
這樣我就無能為力了。。。

TOP

回復 32# ahsiek
修改一下23樓  ButtonStop1 和 SetTimer1

Sub ButtonStop1(Optional sSheetName As String)   '工作表停止按鈕
  gbIsRunning1 = False
  
  On Error Resume Next
  '取消下次執行時間
  Application.OnTime gNextRunTime1, "'SetTimer1 """ & IIf(sSheetName <> "", sSheetName, ActiveSheet.Name) & """'", , False
  On Error GoTo 0
End Sub


Sub SetTimer1(sSheetName As String)
  Const MAX_ROW = 270
  
  gNextRunTime1 = Now + TimeValue("00:00:10")
  Application.OnTime gNextRunTime1, "'SetTimer1 """ & sSheetName & """'"
  
  If mainFunc(sSheetName) >= MAX_ROW Then ButtonStop1 sSheetName '執行並回傳row
End Sub

TOP

回復 34# ahsiek
就像紅字標的地方,修改之前使用ActiveSheet.Name
是當前工作表名稱,因為ButtonStop1被呼叫時可能在別的sheet
,改成指定的工作表而已

TOP

        靜思自在 : 甘願做、歡喜受。
返回列表 上一主題