Board logo

標題: [發問] VBA_請簡化程式碼。謝謝! [打印本頁]

作者: Airman    時間: 2015-11-21 11:07     標題: VBA_執行階段錯誤 "1004" 的修正。

本帖最後由 Airman 於 2015-11-21 11:09 編輯

執行到列9彈出︰
執行階段錯誤  "1004"
Class Range 的 Select方法失敗


請問︰要如何修正?  謝謝!
Private Sub CommandButton1_Click()
Dim J%, K%, tx%, ty%, tz%, b

With Sheets(2)
      Sheets(1).Range("J7", "P" & Sheets(2).[R6] + 5).Copy .[J7]
      tx = .[R7].End(xlDown).Row
      ty = .[T5].End(xlToRight).Column
      For tz = 20 To ty
      .Range("T7:T" & tx).Select
      For Each b In Selection
      If b <> "" Then
  For J = 10 To 16
    For K = 10 To 16
      If .Range("R" & b.Row) + 1 = .[T5] Then
       If .Range("R" & b.Row) - .[T3] * 2 > 6 Then
         If .Cells(.[T5] + 6, J) = .[R5] Then
         If .Cells(.[T5] - 6, J) = .[R5] Then
         If .Cells(.[T5] + 6, J) = .[R5] Then
          With .Cells(.[T5] + 6, J): .Interior.ColorIndex = 4: .Font.ColorIndex = 3: .Font.FontStyle = "粗體": End With
          With .Cells(.[T5] - .[T3] + 6, J): .Interior.ColorIndex = 45: .Font.ColorIndex = 3: .Font.FontStyle = "粗體": End With
          With .Cells(.[T5] - .[T3] * 2 + 6, J): .Interior.ColorIndex = 8: .Font.ColorIndex = 3: .Font.FontStyle = "粗體": End With         
         End If
         End If
         End If
       End If
      End If
    Next K
  Next J
      End If
      Next b
      Next tz
End With
[A1].Select
End Sub
作者: 准提部林    時間: 2015-11-21 12:42

操作程式時, Sheets(2)不是當前工作表, 須先跳轉:
With Sheets(2)
        .Select
      .Range("T7:T" & tx).Select 這行才不會錯誤

不過, 工作表跳轉若非必要, 可:
      For Each b In .Range("T7:T" & tx)  '不用Selection, 上兩行可刪去
作者: Airman    時間: 2015-11-21 14:08

本帖最後由 Airman 於 2015-11-21 14:17 編輯

[回復 2# 准提部林
[attach]22530[/attach]
准大:
感謝指導~
依照貴解修正後,變成會中斷在[A1].Select
將其點掉後,即可完成執行。

但執行完畢後,列19~列21的T5,T5-T3,T5-T3*2之R5顏色標示完全沒有出來~不知小弟還有那裡寫錯了:funk: ~
敬請您再惠予賜正~感恩!

PS:另再請教︰列33 [A1].Select如果點掉,又要如何修正? 謝謝您!
作者: 准提部林    時間: 2015-11-21 15:16

回復 3# Airman


    .[A1].Activate
End With

[A1]是Sheets(2)的, 要放在With裡面!
作者: Airman    時間: 2015-11-21 18:31

本帖最後由 Airman 於 2015-11-21 18:32 編輯

回復 4# 准提部林

准大:
[A1].Select改為 [A1].Activate
可完成執行~OK了~謝謝您:D

列19~列21的T5,T5-T3,T5-T3*2之R5顏色還是完全沒有標示出來~不知小弟還有那裡寫錯了:L
T5=91期;T5-T3=82期;T5-T3*2=73期
R5=11  

敬請您再惠予賜正~感恩:lol
作者: 准提部林    時間: 2015-11-21 20:30

本帖最後由 准提部林 於 2015-11-21 20:31 編輯

回復 5# Airman


If .Cells(.[T5] + 6, J) = .[R5] Then
If .Cells(.[T5] - .[T3] + 6, J) = .[R5] Then
If .Cells(.[T5] - .[T3] * 2 + 6, J) = .[R5] Then
~~
~~
~~
End If
End If
End If

看不懂為何這樣寫,須三個if都成立,才進行之內的操作,
是否應各自分段:
If .Cells(.[T5] + 6, J) = .[R5] Then
~~
End If
If .Cells(.[T5] - .[T3] + 6, J) = .[R5] Then
~~
End If
If .Cells(.[T5] - .[T3] * 2 + 6, J) = .[R5] Then
~~
End If
作者: Airman    時間: 2015-11-21 23:47

回復 6# 准提部林
准大:
If .Cells(.[T5] + 6, J) = .[R5] Then
~~
End If
單獨條件即標示顏色是沒有問題。

但小弟的意思,是想要當T5,T5-T3,T5-T3*2等三個期數(91,82,73)都有顯示R5值(=11)~
3個條件同時成立才標示顏色~所以將3個If...條件...Then擺前面~但顯然是小弟的語法錯誤,才會程式執行完畢卻無顏色標示

請問:
當T5,T5-T3,T5-T3*2等三個期數(91,82,73)同時都有顯示R5值(=11)時~
則3個期數顯示R5值的儲存格標示顏色之正確語法,應該如何寫?

敬請您再次惠予賜正~感恩
作者: Airman    時間: 2015-11-22 00:26

回復 5# Airman
准大:
因您的提示~知道錯誤的程式碼在何處~
剛剛試將程式碼改為~
         If .Cells(.[T5] + 6, I) = .[R5] Then
         If .Cells(.[T5] - .[T3] + 6, J) = .[R5] Then
         If .Cells(.[T5] - .[T3] * 2 + 6, K) = .[R5] Then
           With .Cells(.[T5] + 6, I): .Interior.ColorIndex = 4: .Font.ColorIndex = 3: .Font.FontStyle = "粗體": End With
           With .Cells(.[T5] - .[T3] + 6, J): .Interior.ColorIndex = 45: .Font.ColorIndex = 3: .Font.FontStyle = "粗體": End With
           With .Cells(.[T5] - .[T3] * 2 + 6, K): .Interior.ColorIndex = 8: .Font.ColorIndex = 3: .Font.FontStyle = "粗體": End With
         End If
         End If
         End If
即可完成顏色標示。

但請問:只能這樣寫嗎?
敬請您再惠予賜正~感恩

PS:因為後續還有程式要接續,變數豈不是多的令人撩亂。
作者: GBKEE    時間: 2015-11-22 07:05

回復 8# Airman
試試看
  1. Option Explicit
  2. Sub Ex()
  3.     Dim Rng As Range, E As Variant, C As Variant
  4.     With Sheets(2)
  5.         Sheets(1).Range("J7", "P" & Sheets(2).[R6] + 5).Copy .[J7]
  6.         Set Rng = .[J7].Resize(.[J7].End(xlDown).Row, 7)
  7.         For Each E In Array(.[T5], .[T5] - .[T3], .[T5] - .[T3] * 2)
  8.                             '.T5,T5-T3,T5-T3*2 '91,82,73
  9.             C = Application.Match(.[R5], Rng.Rows(E), 0) '找到傳回數字
  10.             If IsNumeric(C) Then
  11.                 With Rng.Rows(E).Cells(C)
  12.                     .Interior.ColorIndex = 4
  13.                     .Font.ColorIndex = 3
  14.                     .Font.FontStyle = "粗體"
  15.                 End With
  16.             End If
  17.         Next
  18.     End With
  19. End Sub
複製代碼

作者: Airman    時間: 2015-11-22 08:33

回復 9# GBKEE
GBKEE超級版大:
感謝您的不吝賜教與指導~測試OK了~完全符合需求~感恩

PS:程式碼簡化許多~小弟得慢慢消化學習
作者: 准提部林    時間: 2015-11-22 18:55

本帖最後由 准提部林 於 2015-11-22 18:57 編輯

三列〔同時〕出現 [R5],填入不同底色

Private Sub CommandButton1_Click()
Dim b As Range, RW, y%
With Sheets(2)
   Sheets(1).Range("J7", "P" & Sheets(2).[R6] + 5).Copy .[J7]
   Application.Goto .Range("T7:T" & .[R7].End(xlDown).Row) '不用Select,直接跳選目標區 
   RW = Array(.[T5], .[T5] - .[T3], .[T5] - .[T3] * 2) '3區的期數陣列 
   For Each b In Selection
     If b <> "" Then
     If .Range("R" & b.Row) + 1 = .[T5] And .Range("R" & b.Row) - .[T3] * 2 > 6 Then
       Dim R(1 To 3) As Range, U%
       For y = 1 To 3
         Set R(y) = .[J:P].Rows(RW(y - 1) + 6).Find(.[R5], Lookat:=xlWhole) '標定3區[R5]值的儲存格 
         If R(y) Is Nothing Then U = 1: Exit For '若任一區不含 [R5],以 U=1 表示,跳出 
       Next y
       If U = 0 Then '3區皆含[R5]
         For y = 1 To 3: R(y).Interior.ColorIndex = Array(4, 45, 8)(y - 1): Next '標示〔個別〕底色 
         With Union(R(1), R(2), R(3)).Font: .ColorIndex = 3: .FontStyle = "粗體": End With '設定文字 
       End If
     End If
     End If
   Next b
   .[A1].Select
End With
End Sub

可簡化的不多,參考超板的方法減少三層的迴圈而已! 
作者: Airman    時間: 2015-11-22 19:56

回復 11# 准提部林
准大:
您的助人熱誠實在令小弟折服

少了3個迴圈變數就少了許多,除了簡化程式碼,效率也提升很多~,
尤其是不用Select~對於效率的提升更是顯著。

萬分感謝您的耐心教導和費神的再加程式註解~小弟受益良多~感恩再感恩....
作者: 准提部林    時間: 2015-11-22 20:31

回復 12# Airman


只憑所提供的程式碼, 要回溯原需求規則, 除費時費眼力外, 並非易事,
還好有超板專業老手打先鋒, 我插花寫不同需求罷了~~
作者: Airman    時間: 2015-11-23 01:10

本帖最後由 Airman 於 2015-11-23 01:12 編輯

回復 13# 准提部林
准大:
再次謝謝您的費神。

可否另外再請您賜教:
如何將Set R(y) = .[J:P].Rows(RW(y - 1) + 6).Find(.[R5], Lookat:=xlWhole) 改為~
"標定3區[R5]值的儲存格為相同欄位" 。
謝謝您!

為了免於重述繁(煩)複的說明及多占版面,所以未另開題請益~敬請見諒!感恩!
作者: Airman    時間: 2015-11-23 06:20     標題: VBA_請簡化程式碼。謝謝!

需求︰
請將『搜尋在R7(=90期),R7-T3(=81期),R7-T3*2(=72期)三個期數同時有一個(含)以上交集值(=07,39);並分別將其標示4,45,8號底色』的列19~列33程式碼~簡化為如列7~列17之程式碼的型態寫法~
EX︰RV = Array(.Range("R" & b.Row),.Range("R" & b.Row)- .[T3],.Range("R" & b.Row)- .[T3] * 2)  '另3區的期數陣列

詳如附件~[attach]22557[/attach][attach]22557[/attach]


敬請各位大大不吝指導~感恩!
作者: GBKEE    時間: 2015-11-23 06:36

回復 11# 准提部林
字串用 InStr , Split
  1. Option Explicit
  2. Sub Ex()
  3.     Dim Rng As Range, E As Variant, C As Variant, Ar As String
  4.     Ar = "4,45,8"
  5.     With Sheets(2)
  6.         Sheets(1).Range("J7", "P" & Sheets(2).[R6] + 5).Copy .[J7]
  7.         Set Rng = .[J7].Resize(.[J7].End(xlDown).Row, 7)
  8.         For Each E In Array(.[T5], .[T5] - .[T3], .[T5] - .[T3] * 2)
  9.                             '.T5,T5-T3,T5-T3*2 '91,82,73
  10.             C = Application.Match(.[R5], Rng.Rows(E), 0) '找到傳回數字
  11.             If IsNumeric(C) Then
  12.                 With Rng.Rows(E).Cells(C)
  13.                     .Interior.ColorIndex = Split(Ar, ",")(0)
  14.                     .Font.ColorIndex = 3
  15.                     .Font.FontStyle = "粗體"
  16.                 End With
  17.                 If InStr(Ar, ",") Then Ar = Mid(Ar, InStr(Ar, ",") + 1)
  18.             End If
  19.         Next
  20.     End With
  21. End Sub
複製代碼

作者: Airman    時間: 2015-11-23 07:53

回復 16# GBKEE
GBKEE超大:早安!
不好意思,先請教:要讓貴程式在結束後,滑鼠停留在A1,要怎麼寫?(在End With插入.[A1].Activate或.[A1].Select都不對 )

回應貴留言:
小弟的意思是將列19~列33程式碼移除,簡化成如類似列7~列17程式碼型態的寫法。
當然以貴寫法更為簡化。
如不嫌棄~敬請您惠予賜教!感恩
作者: GBKEE    時間: 2015-11-23 08:06

回復 17# Airman
  1. With Sheets(2)
  2.    ' 如准提部林版主 的
  3.     Application.Goto .Range("T7:T" & .[R7].End(xlDown).Row) '不用Select,直接跳選目標區 
  4.    '或 .Activate   
  5.   '或 .Select
  6.    '使Sheets(2) 為作用中工作頁,儲存格才可用.Activate 或.Select
  7.     '
  8.     .[A1].Activate   
  9. '或.[A1].Select
  10. End With
複製代碼
請在指明要簡化的程式碼在哪裡
作者: Airman    時間: 2015-11-23 08:52

回復 18# GBKEE
GBKEE超大:您好!
抱歉!小弟說的太囉嗦了,讓您誤解了~重新說明如下:
請教:
以貴#13的程式碼,如果要再增加~
1.『搜尋在R7(=90期),R7-T3(=81期),R7-T3*2(=72期)三個期數同時有一個(含)以上的交集值(=07,39);並分別將其標示4,45,8號底色』~
應該怎麼再增寫?
2.程式執行結束後,滑鼠停留在A1,請問要怎麼增寫?

以上敬請惠予賜教!謝謝您!
作者: GBKEE    時間: 2015-11-23 09:40

回復 19# Airman
試試看
  1. Option Explicit
  2. Sub Ex()
  3.     Dim Rng As Range, E As Variant, C As Variant, Ar As String, x_No, x As Variant
  4.     x_No = Array(7, 39)
  5.     Ar = "4,45,8"
  6.     With Sheets(2)  '
  7.     'With Sheets("Sheet1")
  8.         .Activate   '將目前的工作表成為使用中的工作表。等同於按一下工作表索引標籤。

  9.         Sheets(1).Range("J7", "P" & Sheets(2).[R6] + 5).Copy .[J7]
  10.         Set Rng = .[J7].Resize(.[J7].End(xlDown).Row, 7)
  11.         For Each E In Array(.[T5].Value, .[T5] - .[T3], .[T5] - .[T3] * 2) '期別的迴圈
  12.             '『搜尋在R7(=90期),R7-T3(=81期),R7-T3*2(=72期)三個期數~
  13.             '.T5,T5-T3,T5-T3*2 '91,82,73 請修改公式
  14.             
  15.             For Each x In x_No   '比對數字的迴圈
  16.                 C = Application.Match(x, Rng.Rows(E), 0) '找到傳回數字
  17.                 If IsNumeric(C) Then
  18.                     With Rng.Rows(E).Cells(C)
  19.                         .Interior.ColorIndex = Split(Ar, ",")(0)
  20.                         .Font.ColorIndex = 3
  21.                         .Font.FontStyle = "粗體"
  22.                     End With
  23.                 End If
  24.             Next
  25.             If InStr(Ar, ",") Then Ar = Mid(Ar, InStr(Ar, ",") + 1)
  26.         Next
  27.         .[a1].Select  '滑鼠停留在Sheets(2)的 A1
  28.     End With
  29. End Sub
複製代碼

作者: Airman    時間: 2015-11-23 10:20

本帖最後由 Airman 於 2015-11-23 10:24 編輯

回復 20# GBKEE
GBKEE超大:
不好意思,有點誤差~但不好說明,小弟盡力就是~
07,39只是舉例符合範例中之期數的交集數字,~所以交集數字是依據有數字的T欄之對應R欄期數而變化。

因此~小弟將列12改為:
For Each E In Array(.Range("R" & b.Row).Value, .Range("R" & b.Row) - .[T3], .Range("R" & b.Row) - .[T3] * 2) '期別的迴圈
程式就中斷了。

請教:
x_No = Array(7, 39)和"期別的迴圈"或其它相關的程式碼應如何再修正?
敬請賜正!謝謝您:lol

PS:交集的數字範圍:01~49。可能有1個,可能有2個,....最多7個。
作者: GBKEE    時間: 2015-11-23 11:33

回復 21# Airman
你想要某一期數中開出的號碼(最多7個)或是指定的號碼,在下幾期中標出顏色
數字範圍:01~49。可能有1個,可能有2個,....最多7個。   
所以交集數字是依據有數字的T欄之對應R欄期數而變化

你的規律邏輯 ,附檔中可指明嗎? 說清楚.


  1. For Each E In Array(.Range("R" & b.Row).Value, .Range("R" & b.Row) - .[T3], .Range("R" & b.Row) - .[T3] * 2)
複製代碼

沒程式碼看不懂 ,
作者: Airman    時間: 2015-11-23 12:11

回復 22# GBKEE
  就如附檔中的列19~列33
For i = 10 To 16
   For j = 10 To 16
    For k = 10 To 16
           If .Cells(.Range("R" & b.Row) + 6, i) = .Cells(.Range("R" & b.Row) - .[T3] + 6, j Then
           If .Cells(.Range("R" & b.Row) + 6, i) = .Cells(.Range("R" & b.Row) - .[T3] * 2 + 6, k) Then
           If .Cells(.Range("R" & b.Row) - .[T3] + 6, j) = .Cells(.Range("R" & b.Row) - .[T3] * 2 + 6, k) Then
              .Cells(.Range("R" & b.Row) + 6, i).Interior.ColorIndex = 4
              .Cells(.Range("R" & b.Row) - .[T3] + 6, j).Interior.ColorIndex = 45
              .Cells(.Range("R" & b.Row) - .[T3] * 2 + 6, k).Interior.ColorIndex = 8
           End If
           End If
           End If

簡單的說:就是將上述程式碼的需求化為貴程式碼~然後將上述的程式碼移除即可。

可能是因為貴程式碼少了類似#11的程式碼~
Application.Goto .Range("T7:T" & .[R7].End(xlDown).Row)

For Each b In Selection
If b <> "" Then
...
Next b
所以(.Range("R" & b.Row) 套不進去貴程式中之"期別的迴圈"~
小弟VBA初學,只是猜測可能的原因~不敢就此妄斷

以上 謹供參考!謝謝您!
作者: 准提部林    時間: 2015-11-23 18:26

回復 14# Airman


If R(y) Is Nothing Then U = 1: Exit For
底下加一行:
If y > 1 Then If R(y).Column <> R(y-1).Column Then U = 1: Exit For '三區任一欄位不同 
作者: Airman    時間: 2015-11-23 19:01

回復 24# 准提部林
准大:
測試OK了~感恩
小弟以為要改為Offset,弄了老半天,就是跑不出結果

#15可否請您再次指導~謝謝您
作者: 准提部林    時間: 2015-11-23 20:58

回復 23# Airman

雖有原來的程式碼,沒有文字詳細說明規則,及舉實例說明,超板應很不好下手去做簡化;

程式碼自己寫的,自己看得懂,要修改時還有個下手處,所以小幅修改如下:
For i = 10 To 16:  For j = 10 To 16:  For k = 10 To 16
  If .Cells(b(1, -1) + 6, i) = .Cells(b(1, -1) - .[T3] + 6, j) And _
    .Cells(b(1, -1) + 6, i) = .Cells(b(1, -1) - .[T3] * 2 + 6, k) Then
    .Cells(b(1, -1) + 6, i).Interior.ColorIndex = 4
    .Cells(b(1, -1) - .[T3] + 6, j).Interior.ColorIndex = 45
    .Cells(b(1, -1) - .[T3] * 2 + 6, k).Interior.ColorIndex = 8
  End If
Next k:  Next j:  Next i

=====================================
.Cells(.Range("R" & b.Row) + 6, i) 改成 .Cells(b(1, -1) + 6, i) _b格往左2格即為R欄的期數格
3個If改成2個即可,A=B and A=C 即必定A=C
作者: 准提部林    時間: 2015-11-23 21:01

回復 23# Airman

若要3列同欄相同:
For i = 10 To 16
  If .Cells(b(1, -1) + 6, i) = .Cells(b(1, -1) - .[T3] + 6, i) And _
    .Cells(b(1, -1) + 6, i) = .Cells(b(1, -1) - .[T3] * 2 + 6, i) Then
    .Cells(b(1, -1) + 6, i).Interior.ColorIndex = 4
    .Cells(b(1, -1) - .[T3] + 6, i).Interior.ColorIndex = 45
    .Cells(b(1, -1) - .[T3] * 2 + 6, i).Interior.ColorIndex = 8
  End If
Next i
作者: Airman    時間: 2015-11-24 01:38

本帖最後由 Airman 於 2015-11-24 01:44 編輯

回復 27# 准提部林
准大:
感謝您的賜教!多學習了另種程式寫法。感恩:lol

"程式碼自己寫的,自己看得懂"
小弟可能是在"認知上"有誤解了~超版大都已經看得懂貴語法~
因為自己覺得小弟寫的是最粗淺一條一條逐條敘述的語法,而且有範例,以為大家應該都看得懂,所以沒有再加註~
這一點經您一說,對超版大深覺抱歉!在此特向超版大謹致歉意:L

其實這次會想簡化程式碼,起因是想儘量少用迴圈,除了提升執行效率也減少變數得使用,再者是拜讀您簡化的語法後,覺得很接近A知識長的寫法~
且更簡扼易懂,然後又拜讀超版大的語法,又更簡呃,所以才又將交集值語法提出簡化需求~
給二位先進添麻煩,深感不安,敬請涵諒!
作者: Airman    時間: 2015-11-24 02:56

本帖最後由 Airman 於 2015-11-24 03:07 編輯

回復 22# GBKEE
超版大:
抱歉!小弟覺得自己寫的是最粗淺一條一條逐條敘述的語法,而且有範例,所以沒有再加註~不察之處,敬請涵量:L

小弟有將貴程式嘗試添修~
        Sheets(1).Range("J7", "P" & Sheets(2).[R6] + 5).Copy .[J7]

        'Set Rng = .Range("T7:T" & .[R7].End(xlDown).Row)        
       Application.Goto .Range("T7:T" & .[R7].End(xlDown).Row)        
        For Each b In Selection
        
         If b <> "" Then        
        E = Array(.Range("R" & b.Row).Value, .Range("R" & b.Row) - .[T3], .Range("R" & b.Row) - .[T3] * 2) '期別的陣列

            For Each x In x_No   '比對數字的迴圈             .
              ......
             ......
         End If
       Next b

因不知 x_No = Array(7, 39)等交集數字的相關語法要怎麼改?所以只這樣添加~程式會中斷在For Each x In x_No

交集數字取得的邏輯
T欄有顯示數字的儲存格,且當其在R欄的對應期數(即.Range("R" & b.Row))及該R欄的對應期數-T$3(即.Range("R" & b.Row)-T$3)及該R欄的對應期數-T$3*2(即.Range("R" & b.Row)-T$3*2)等3個期數同時都有相同數字,則該相同數字即為3個期數的交集值

本題需求說明:
T欄有顯示數字的儲存格,且當其在R欄的對應期數(即.Range("R" & b.Row))及該R欄的對應期數-T$3(即.Range("R" & b.Row)-T$3)及該R欄的對應期數-T$3*2(即.Range("R" & b.Row)-T$3*2)~
等3個期數有一個(含)以上的交集值時,則交集值的儲存格標示4,45,8底色。
EX︰範例中的T96有顯示數字,且其對應R欄的期數(90)及該R欄的對應期數-T$3(90-9=81)及該R欄的對應期數-T$3*2(90-9*2=72)~
等3個期數有一個(含)以上的交集值(07,39)時,則J96,P96標示4號底色;K87,M87標示45號底色;J78,K78標示8號底色。

以上 謹供參考!謝謝您!

[attach]22577[/attach][attach]22577[/attach]
作者: Airman    時間: 2015-11-24 05:21

回復 26# 准提部林
准大:您好!
不好意思,恕小弟執著,還是希望您能賜教如11#的寫法~
因為11#的貴語法,同欄不限同欄的區分~只要多加一列程式碼~
f y > 1 Then If R(y).Column <> R(y-1).Column Then U = 1: Exit For
非常簡捷便利。

懇請您撥冗惠予賜教為禱~感恩 

小弟以貴程式依樣畫葫蘆~嘗試做個範例:
[attach]22578[/attach]
謹供參考!謝謝您!
作者: GBKEE    時間: 2015-11-24 06:55

回復 29# Airman
有一個(含)以上的交集值(07,39)時
交集值 應有規律性,可讓程式去設定
試試看
  1. Option Explicit
  2. Private Sub CommandButton1_Click()
  3.     Dim b As Range, Rng As Range, E, C As Variant, Ar(), x_No, x As Variant
  4.     Dim xRng As Range, Color_Ar(), i As Integer
  5.     x_No = Array(7, 39)
  6.     Color_Ar = Array(4, 45, 8)
  7.     With Sheets(2)
  8.         .Activate   '將目前的工作表成為使用中的工作表。等同於按一下工作表索引標籤。
  9.         Sheets(1).Range("J7", "P" & Sheets(2).[R6] + 5).Copy .[J7]
  10.         Set Rng = .Range("J7:P" & .[R6] + 5)                '所複製資料的範圍
  11.         Set xRng = .Range("T7:T" & .[R6] + 5)               'T欄的範圍
  12.         If Application.Count(xRng) = 0 Then Exit Sub        'T欄沒有期數時離開程式
  13.         For Each b In xRng.SpecialCells(xlCellTypeConstants) 'T欄 [有期數的儲存格]範圍
  14.             Ar = Array(.Range("R" & b.Row).Value, .Range("R" & b.Row) - .[T3], .Range("R" & b.Row) - .[T3] * 2) '期別的陣列
  15.             '陣列:其在R欄的對應期數
  16.             For i = 0 To UBound(Ar)                 '陣列元素下限值從0開使
  17.                 For Each x In x_No                  '比對數字的迴圈
  18.                     C = Application.Match(x, Rng.Rows(Ar(i)), 0) '找到傳回數字
  19.                     If IsNumeric(C) Then Rng.Rows(Ar(i)).Cells(C).Interior.ColorIndex = Color_Ar(i)
  20.                 Next
  21.             Next
  22.         Next
  23.         .[a1].Select  '滑鼠停留在Sheets(2)的 A1
  24.     End With
  25. End Sub
複製代碼

作者: Airman    時間: 2015-11-24 09:54

本帖最後由 Airman 於 2015-11-24 10:01 編輯

回復 31# GBKEE
GBKEE超版大:您好!
不好意思,您還將程式碼全加註解~辛苦您了!感恩

非常接近了!只剩下交集值定義有誤差~
先假設ARR=.Range("R" & b.Row),.Range("R" & b.Row)-T$3, .Range("R" & b.Row)-T$3*2三個期數的範圍,以利說明。

目前貴程式是依據x_No = Array(m, n)是預設之固定的搜尋值~
即當m填入07n填入39,則將在ARR有顯示0739的儲存格各標示底色(不需要3個期數同時都有);
又如當m填入01n填入49,則將在ARR有顯示0149的儲存格各標示底色(不需要3個期數同時都有);....其餘以此類推。

本體需求交集值浮動的(即預設的)~
即是依據ARR的3個期數是否同時都有相同數字來決定︰如果3個期數都有相同的數字時,則該相同數字即為交集值~
EX1_即當ARR交集值01(即必須3個期數同時都有01)時,則3個期數顯示01的儲存格各標示底色;
EX2_即當ARR交集值07,39(即必須3個期數同時都有07,39)時,則3個期數顯示07,39的儲存格各標示底色;
EX3_ARR交集值08,20,40(即必須3個期數同時都有08,20,40)時,則3個期數顯示08,20,40的儲存格各標示底色;
EX4_ARR都沒有交集值(即3個期數沒有同時都有相同的數字)時,則3個期數的儲存格都為無底色。..... 其餘以此類推。

以上 謹供參考!謝謝您!
作者: 准提部林    時間: 2015-11-24 11:10

本帖最後由 准提部林 於 2015-11-24 12:18 編輯

回復 30# Airman


x_No = Array(7, 39) 超板還是以為7,39是〔已知〕條件,所以我才說要加註說明!!^ ^

試著以如下去解說:
有A.B.C三區,每區7格,每區各有7個1~49不重覆數字,
找出這三區〔共有〕的數字並分別填入底色 (共有數字須先行檢測,無預設值),
例如下方範例,檢測後取得共同數字為:07.39.13
A區:
07121728394313

B區:
01071339424549

C區:
07091320213949

=====================================
#11 是以〔一個數字〕去比封三區,所以較簡單,
此需求是7個數字逐一比對三區,1 To 3 及 1 To 7 迴圈省不了,因為欄位不一樣,
若要求數字及欄位相同,即如#27,用 1 To 7 迴圈即可,反而較省事;
以此需求的迴圈不算大,應還不太影響運行速度,
若減少迴圈以函數代替,也並不見得較好,畢竟函數的效率有時會降低速度~~
作者: Airman    時間: 2015-11-24 11:45

回復 33# 准提部林
准大:
呵~呵~還是您的解說既簡且清~小弟承教了~希望小弟下次的說明能更精準

原是想程式碼同一式體,既然您說沒有特別益處~小弟就不再執著了。

謝謝您的耐心回覆與說明~感恩
作者: GBKEE    時間: 2015-11-24 13:13

本帖最後由 GBKEE 於 2015-11-24 14:45 編輯

回復 34# Airman

參考准提部林 版主說明
試試看
  1. Option Explicit
  2. Dim Sh As Worksheet '這模組的私用變數
  3. Private Sub CommandButton1_Click()
  4.     Dim b As Range, Rng As Range
  5.     Dim xRng(1 To 2) As Range
  6.     With Sheets("Sheet1") '要呈現的工作表
  7.         Sheets("DATA").Range("J7", "P" & .[R6] + 5).Copy .[J7]
  8.         Set Rng = .Range("J7:P" & .[R6] + 5)                   '所複製資料的範圍
  9.         Rng.Interior.ColorIndex = xlNone
  10.         Set xRng(1) = .Range("T7:T" & .[R6] + 5)               'T欄的範圍
  11.         If Application.Count(xRng(1)) = 0 Then Exit Sub        'T欄沒有期數時離開程式
  12.         
  13.         Set Sh = Sheets.Add(Sheets(1))                         '增加一工作表
  14.         Application.ScreenUpdating = False                     '如果螢幕更新功能是開啟的則為 True
  15.         For Each b In xRng(1).SpecialCells(xlCellTypeConstants) 'T欄 [有期數的儲存格]範圍
  16.             Ex_ChiCK Union(Rng.Rows(.Range("R" & b.Row)), Rng.Rows(.Range("R" & b.Row) - .[T3]), Rng.Rows(.Range("R" & b.Row) - .[T3] * 2))  '期別的陣列
  17.             'Ex_ChiCK Union(Rng.Rows(.Range("R" & b.Row) - .[T3] * 2), Rng.Rows(.Range("R" & b.Row) - .[T3]), Rng.Rows(.Range("R" & b.Row)))  '倒轉期別
  18.         Next
  19.         .Activate   '將目前的工作表成為使用中的工作表。等同於按一下工作表索引標籤。
  20.         .[a1].Select  '滑鼠停留在Sheets(2)的 A1
  21.     End With
  22.     Application.DisplayAlerts = False  '如果巨集在執行時 Microsoft Excel 顯示特定的警告和訊息則為 True
  23.     Sh.Delete                          '刪除:工作表
  24.     Application.DisplayAlerts = True
  25.     Application.ScreenUpdating = True
  26. End Sub
  27. Private Sub Ex_ChiCK(Rng As Range)  '副程式 須傳送參數
  28.     Dim Ar(), i As Variant, E As Variant, X As Variant, M As Integer
  29.     Ar = Array(4, 45, 8)
  30.     Rng.Copy Sh.[a1]             '複製三期資料
  31.     For i = 1 To 49
  32.         X = Application.CountIf(Sh.UsedRange, i)  'x = 3 :同一號碼三期都出現
  33.         If X = 3 Then E = E & IIf(E <> "", ",", "") & i  '紀錄號碼
  34.     Next
  35.     X = Split(E, ",")        '出現3次的號碼,置入陣列
  36.     For Each E In X
  37.         For i = 1 To Rng.Areas.Count
  38.             '傳回 Areas 集合,此集合代表多重範圍中的所有範圍
  39.             M = Application.Match(Val(E), Rng.Areas(i).Cells, 0)
  40.             Rng.Areas(i).Cells(M).Interior.ColorIndex = Ar(i - 1) '依範圍傳回的顏色
  41.         Next
  42.     Next
  43. End Sub
複製代碼

作者: Airman    時間: 2015-11-24 14:20

本帖最後由 Airman 於 2015-11-24 14:24 編輯

回復 35# GBKEE
GBKEE超版大:您好!
不好意思~只剩標示底色的問題了~
假設:A區=.Range("R" & b.Row);B區=.Range("R" & b.Row)-T$3;C區=.Range("R" & b.Row)-T$3*2;
則3區的共有數字,依分區分別標示4號,45號,8號底色~即A區標示4號底色;B區標示45號底色;C區標示8號底色 ~
EX_1:
C區(72):         07        10        13        20        21        39        18

B區(81):        01        07        13        39        42        45        12

A區(90):        07        12        17        28        40        41        49

EX_2:
C區(72):         07        09        11        20        21        39        12

B區(81):        01        07        13        39        42        45        10

A區(90):        07        12        17        28        40        13        39

EX_3:
C區(72):         07        09        13        20        21        39        12

B區(81):        01        07        13        39        42        45        12

A區(90):        07        10        17        28        40        13        39


EX_4:
C區(72):         07        09        13        20        21        39        12

B區(81):        01        07        13        39        42        45        12

  A區(90):        07        12        17        28        40        13        39

.....其餘以此類推

以上 謹供參考!謝謝您!
作者: 准提部林    時間: 2015-11-24 21:07

不是簡化,另一種寫法,比原使用3層迴圈更不易理解,參考罷:

RW = Array(b(1, -1), b(1, -1) - .[T3], b(1, -1) - .[T3] * 2)
For y = 1 To 3: Set R(y) = .[J:P].Rows(RW(y - 1) + 6).Cells: Next y
Dim M(1 To 3)
For k = 1 To 7
  M(1) = k
  For y = 2 To 3
    M(y) = Application.Match(R(1)(k), R(y), 0)
    If IsError(M(y)) Then M(1) = 0: Exit For
    'If M(y) <> M(1) Then M(1) = 0: Exit For '若要求〔同欄〕,加入這行 
  Next y
  If M(1) > 0 Then
   For y = 1 To 3: R(y)(M(y)).Interior.ColorIndex = Array(4, 45, 8)(y - 1): Next
  End If
Next k
作者: Airman    時間: 2015-12-9 09:25

回復 37# 准提部林
准大:
感謝您費神再賜另解

PS:本想只以短消息向您致謝即可,避免虛取點數,但無奈小弟還是不習慣~總覺得問與答之間少個句點




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)