返回列表 上一主題 發帖

[發問] 此巨集為何錯??

本帖最後由 luhpro 於 2013-8-3 00:01 編輯

回復 4# t8899
因為沒實際的檔案資料可以驗證結果,
試試看底下的程式碼是否符合你的需求.
  1.   Dim sStr$
  2.   Dim xx As Range

  3.   sStr = ""
  4.   For Each xx In Range("AG2:AG111")
  5.     If Not IsError(xx) Then
  6.       If xx > xx.Offset(, -1) And Range("Q24").Value = 1 And flag = True Then
  7.         If sStr <> "" Then sStr = sStr & Chr(10)
  8.         sStr = sStr & "===> " & Cells(xx.Row, 2).Value & "=====> " & xx.Value
  9.         Range("Q24").Value = 2
  10.         Application.OnTime Now + TimeValue("00:00:15"), "DDD"
  11.         Exit For
  12.       End If
  13.     End If
  14.   Next
  15.   If sStr <> "" Then CreateObject("Wscript.shell").Popup sStr, 1, "Auto Closed MsgBox", 64
複製代碼

TOP

回復 6# t8899
把 Exit For 拿掉,
不然當條件成立後,
迴圈只會執行一次.
  1. Private Sub Worksheet_Calculate()
  2.   Dim sStr$
  3.   Dim xx As Range

  4.   sStr = ""
  5.   For Each xx In Range("f2:F54")
  6.     If Not IsError(xx) Then
  7.       If xx > xx.Offset(, -1) And Range("I1").Value = 1 Then
  8.         If sStr <> "" Then sStr = sStr & Chr(10)
  9.         sStr = sStr & "===> " & Cells(xx.Row, 2).Value & "=====> " & xx.Value
  10.         'Exit For    <===== 拿掉
  11.       End If
  12.     End If
  13.   Next
  14.   If sStr <> "" Then CreateObject("Wscript.shell").Popup sStr, 1, "Auto Closed MsgBox", 64
  15. End Sub
複製代碼

TOP

想再多加一個條件
f2:F54 超過 5個 以上條件才成立
要如何改?
t8899 發表於 2013-8-3 10:08

超過 5個 以上?
那就邊處理邊計數囉:
  1. Private Sub Worksheet_Calculate()
  2.   Dim lCount As Long
  3.   Dim sStr$
  4.   Dim xx As Range

  5.   sStr = ""
  6.   lCount = 0
  7.   For Each xx In Range("f2:F54")
  8.     If Not IsError(xx) Then
  9.       If xx > xx.Offset(, -1) And Range("I1").Value = 1 Then
  10.         If sStr <> "" Then sStr = sStr & Chr(10)
  11.         sStr = sStr & "===> " & Cells(xx.Row, 2).Value & "=====> " & xx.Value
  12.         lCount = lCount + 1
  13.       End If
  14.     End If
  15.   Next
  16.   If sStr <> "" And lCount > 5 Then CreateObject("Wscript.shell").Popup sStr, 1, "Auto Closed MsgBox", 64
  17. End Sub
複製代碼

TOP

回復 11# t8899
相比程式中其他部分的動作來說,

這只是將某個變數做 加1 的動作,

資源消耗幾乎可以不計.

TOP

抱歉,再打擾一下
條件想改成
只有 Range("f2:F54")  變動超過 1% 則條件成立(Range("f2:F54") 為DDE連 ...
t8899 發表於 2013-8-4 09:57

改成這個應該不困難啊:

If Int(xx - xx.Offset(, -1)) >= 0.01 And Range("I1").Value = 1 Then

TOP

本帖最後由 luhpro 於 2013-8-4 22:40 編輯
Range("f2:F54")  變動超過 1%
是自欄跟自欄比較 不是跟 E欄(xx.Offset(, -1)) 比較
即變動後-變動前  ...
t8899 發表於 2013-8-4 22:24

Excel 並不能抓取任一儲存格於 "變動前" 的值,
除非你事先把它存起來,
所以你可以考慮比較完立刻把目前的值存放到該列某欄(或是陣列, Dictionary...)上,
到下次需要時再將目前的值與該欄(或是陣列, Dictionary...)做比較.

至於你說的沒有換行...
If sStr2 <> "" Then sSt2r = sStr2 & Chr(10)
紅字的 2r 與 r2 不同,
這就不是 sStr2 變數了喔.

TOP

本帖最後由 luhpro 於 2013-8-6 23:30 編輯
我上面的就是如此寫的,因為有or判斷
在輸出時,如何改為
1. 如ZZ > ZZ.Offset(, 26) * 1.01 ,則 輸出 "漲" 及 ZZ 與 ZZ.Offset(, 26) * 1.01 之差
2. 如ZZ < ZZ.Offset(, 26) * 1.01 ,則 輸出 "跌" 及 ZZ 與 ZZ.Offset(, 26) * 1.01 之差
t8899 發表於 2013-8-5 04:35

因為沒有你實際的程式內容,
所以只好拿你之前的程式來修改,
你再參照著應用.
  1. Private Sub Worksheet_Calculate()
  2.   Dim lCount As Long, lDir As Long
  3.   Dim sStr$
  4.   Dim ZZ As Range
  5.   Dim rRoF()

  6.   rRoF = Array("跌", "漲")
  7.   sStr = ""
  8.   lCount = 0
  9.   For Each ZZ In Range("f2:F54")
  10.     If Not IsError(ZZ) Then
  11.       lDir = ZZ - ZZ.Offset(, -1)
  12.       If Abs(lDir) > 0.01 And Range("I1").Value = 1 Then
  13.         If sStr <> "" Then sStr = sStr & Chr(10)
  14.         sStr = sStr & "===> " & Cells(ZZ.Row, 2).Value & "=====> " & rRoF(-(lDir > 0)) & " " & Abs(lDir)
  15.         lCount = lCount + 1
  16.       End If
  17.     End If
  18.   Next
  19.   If sStr <> "" And lCount > 5 Then CreateObject("Wscript.shell").Popup sStr, 15, "Auto Closed MsgBox", 64
  20. End Sub
複製代碼
此句 Application.OnTime Now + TimeValue("00:00:15"), "ccc" , 是否會跑 AAA,BBB ??

不會, 你已經指定它去跑 ccc 了,
除非你在 ccc 中有加上 Call AAA 及 Call BBB.

執行巨集時,如何不佔用目前工作表視窗 ??

將不想出現切換動作的地方的 .select 拿掉,(相對的有 Selection 的地方也要修改)
或是在不想畫面變動的區間以
Application.EnableEvents = False 及
Application.EnableEvents = true 包覆.


下面此段工作表有變動,但條件未達到(flag=false),最後一行 Application.OnTime Now + TimeValue("00:00:1 ...
t8899 發表於 2013-8-5 07:21

改成 :
If flag Then Application.OnTime Now + TimeValue("00:00:15"), "DDD"

TOP

下面 兩組條件同時達到條件
不知為何第二組的對話盒不會自動關閉
如果把第二組與第一組先後互換,又換第 ...
t8899 發表於 2013-8-7 19:22

我猜應該是這個函數只有(或是不管呼叫幾次都共用)一個計數器,
當此計數器歸零後除非再次觸發(再呼叫)才會重新計數.

TOP

回復 23# t8899
剛剛想到一個不一定符合你需求的辦法,

在 CreateObject 指令上方放一個條件式,
若還有 CreateObject 指令執行中的話, (分別在兩個 CreateObject 上方放 bFlag1或2 = true下方則設該值為False 作為是否執行中的判斷 )
就暫停兩秒後再執行 CreateObject 指令,
讓其依續錯開,
缺點是若觸發的太頻繁,
可能程式會因為來不及消化而發生異常.

TOP

回復 25# t8899
你的sz(i, 1) 我看到的值是 : 錯誤 2023
這在 VB 來看是一個 字串,
它不讓用 Val() 來轉換成數字,(所以會出現 13 的錯誤)
我建議用 CLng( 來取代 Val(
全部代換即可. (當然前提是類似上述字串的內容, 你仍然希望經過該 Sub 而不是做例外處理)
  1. Sub 檢查()
  2.     Dim n, sz1, str As String

  3.     sz1 = Sheets("Sheet1").Range("F2:F54")
  4.     str = ""
  5.     For i = 1 To UBound(sz1)
  6.         If CLng(sz(1, 1)) = 0 Then
  7.             If CLng(sz1(i, 1)) <> 0# Then str = str & vbCrLf & "單元格 F" & i + 1 & " =========" & "  B" & i + 1 & "=" & Sheets("Sheet1").Cells(i + 1, 2).Value
  8.         Else
  9.             n = Round((CLng(sz1(i, 1)) - CLng(sz(i, 1))) / CLng(sz(i, 1)) * 100, 2)
  10.              If Abs(n) >= 1 Then str = str & vbCrLf & Sheets("Sheet1").Cells(i + 1, 2).Value & "===>" & n
  11.         End If
  12.     Next i

  13.     If Len(str) > 0 Then
  14.         sz = Sheets("Sheet1").Range("F2:F54")
  15.        ' MsgBox str, , "提示"
  16.           CreateObject("Wscript.shell").Popup "" & str, 3, "Auto Closed MsgBox", 64
  17.     End If
  18. End Sub
複製代碼

TOP

        靜思自在 : 待人退一步,愛人寬一寸,就會活得很快樂。
返回列表 上一主題