いつもお世話になっております。
現在大量にセルの内容を参照し、照らし合わせるマクロを作っていますが、内容が膨大でマクロでも
時間がかかるので、何とか高速化できないか、考えております。
そこで、セルを直接参照するより、配列を使った方が速くなるという話を聞いたのですが、
配列を使うときに普通はVariantで宣言をして、セルの値のみ格納すると思います。
例えば、次のように、A列とB列を10000個のセルを1個ずつ比較し、一致した時にある作業をさせて
C列に出力するとします。
A = Range("A1:A10000")
B = Range("B1:B10000")
For i = 1 To 10000
For j = 1 To 10000
If A(i, 1) = B(j, 1) Then
A(i, 1) = A(i, 1) + 1
End If
Next
Next
Range("C1:C10000") = A
このようなマクロならいいのですが、値が一致した時にそのセルの色を変えるだとか削除するだとか行うと、次のようになり、配列のみでの構成ができなくなってしまいます
A = Range("A1:A10000")
B = Range("B1:B10000")
For i = 1 To 10000
For j = 1 To 10000
If A(i, 1) = B(j, 1) Then
Cells(i, 1).Interior.ColorIndex = 3
End If
Next
Next
前者は15秒、後者は19秒かかりました。上のプログラムは例であり、
実際に実務の方でマクロを実行すると数十分かかってしまいます。
何とか、条件によってセルの色変えたり削除するときに、速度を低下させずに配列のみで構成することは不可能でしょうか?
いつもお世話になっております。
現在大量にセルの内容を参照し、照らし合わせるマクロを作っていますが、内容が膨大でマクロでも
時間がかかるので、何とか高速化できないか、考えております。
そこで、セルを直接参照するより、配列を使った方が速くなるという話を聞いたのですが、
配列を使うときに普通はVariantで宣言をして、セルの値のみ格納すると思います。
例えば、次のように、A列とB列を10000個のセルを1個ずつ比較し、一致した時にある作業をさせて
C列に出力するとします。
A = Range("A1:A10000")
B = Range("B1:B10000")
For i = 1 To 10000
For j = 1 To 10000
If A(i, 1) = B(j, 1) Then
A(i, 1) = A(i, 1) + 1
End If
Next
Next
Range("C1:C10000") = A
このようなマクロならいいのですが、値が一致した時にそのセルの色を変えるだとか削除するだとか行うと、次のようになり、配列のみでの構成ができなくなってしまいます
A = Range("A1:A10000")
B = Range("B1:B10000")
For i = 1 To 10000
For j = 1 To 10000
If A(i, 1) = B(j, 1) Then
Cells(i, 1).Interior.ColorIndex = 3
End If
Next
Next
前者は15秒、後者は19秒かかりました。上のプログラムは例であり、
実際に実務の方でマクロを実行すると数十分かかってしまいます。
何とか、条件によってセルの色変えたり削除するときに、速度を低下させずに配列のみで構成することは不可能でしょうか?
エラー発生で強制終了になってしまいます。2007年のexcelで作成したものですが、2010だと強制終了になってしまいます。
内容は□をダブルクリックすると■になるように作っています。
記述は2003年からのマクロ記述なので、変化が必要なのでしょうか?
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
'Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'セルをダブルクリックすると、・→○→△→×→・と変更する。
Dim S1 As String
Dim S2 As String
Dim S01 As String
Dim S02 As String
Dim S03 As String
Dim S04 As String
S1 = "□"
S2 = "■"
S01 = "・"
S02 = "○"
S03 = "△"
S04 = "×"
On Error GoTo ERR_12
sCheckXY S1, S2
sCheckX1234 S01, S02, S03, S04
sChangeXY S1, S2
Exit Sub
ERR_12:
End
End Sub
Sub sChangeXY(X As String, Y As String)
'選択セルに□があれば■に変える
Dim Str0 As String 'str1の左端
Dim Str1 As String 'strの右側更新
Dim Str2 As String 'strの左側更新
Dim Str20 As String 'strの左側一部保存
Dim L As Long
Dim M As Long
Dim N As Long
Str1 = ActiveCell.Text
L = Len(Str1)
Debug.Print L
If L = 0 Then
End
End If
For N = 1 To L
Debug.Print Str2
Str0 = Left(Str1, 1)
If Str0 = X Or N = L Then
If Str20 <> "" Then
If N = L Then
Str20 = Str20 + Str0
End If
If MsgBox(Str20 & " はチェックしますか?", vbYesNo, "選択肢") = vbYes Then
Str2 = Str2 + Replace(Str20, X, Y)
Str20 = Str0
Else
Str2 = Str2 + Replace(Str20, Y, X)
Str20 = Str0
End If
Else
Str20 = Str0
End If
Else
Str20 = Str20 + Str0
End If
Str1 = Right(Str1, L - N)
Next N
ActiveCell.Value = Str2
End Sub
Sub sCheckXY(X As String, Y As String)
'選択セルがXならY,YならXにチェックをかえる
If ActiveCell.Text = X Then
ActiveCell.Value = Y
End
ElseIf ActiveCell.Text = Y Then
ActiveCell.Value = X
End
End If
End Sub
Sub sCheckX1234(X1 As String, X2 As String, X3 As String, X4 As String)
'選択セルがXならY,YならXにチェックをかえる
If ActiveCell.Text = X1 Then
ActiveCell.Value = X2
End
ElseIf ActiveCell.Text = X2 Then
ActiveCell.Value = X3
End
ElseIf ActiveCell.Text = X3 Then
ActiveCell.Value = X4
End
ElseIf ActiveCell.Text = X4 Then
ActiveCell.Value = X1
End
End If
End Sub
早速ですが
入力された値が 時間かそれとも時間でないか識別したいのですが
If IsDate(Cells(1, 2)) Then 日付はあるのですが
If Istime(Cells(1, 2)) Then は 駄目なようです。
If TimeValue(Cells(1, 2)) Then ですと、True なら 良いのですが、逆だとエラーになります。
エラー回避で、識別するのも手ですが、
簡単な方法は無いのでしょうか
for each で配列内の値をいじるマクロを組んでいるのですが
「今 配列内のどこを見ているのか」を取りだすにはどうすればよいのでしょうか
for each c in range(~
の時には「今 range内のどこを見ているのか」は c.address をすればわかったのですが、配列となるとどうすればよいのか…
お分かりになるかたいらっしゃったらよろしくお願いします
for each で配列内の値をいじるマクロを組んでいるのですが
「今 配列内のどこを見ているのか」を取りだすにはどうすればよいのでしょうか
for each c in range(~
の時には「今 range内のどこを見ているのか」は c.address をすればわかったのですが、配列となるとどうすればよいのか…
お分かりになるかたいらっしゃったらよろしくお願いします
エラー発生で強制終了になってしまいます。2007年のexcelで作成したものですが、2010だと強制終了になってしまいます。
内容は□をダブルクリックすると■になるように作っています。
記述は2003年からのマクロ記述なので、変化が必要なのでしょうか?
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
'Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'セルをダブルクリックすると、・→○→△→×→・と変更する。
Dim S1 As String
Dim S2 As String
Dim S01 As String
Dim S02 As String
Dim S03 As String
Dim S04 As String
S1 = "□"
S2 = "■"
S01 = "・"
S02 = "○"
S03 = "△"
S04 = "×"
On Error GoTo ERR_12
sCheckXY S1, S2
sCheckX1234 S01, S02, S03, S04
sChangeXY S1, S2
Exit Sub
ERR_12:
End
End Sub
Sub sChangeXY(X As String, Y As String)
'選択セルに□があれば■に変える
Dim Str0 As String 'str1の左端
Dim Str1 As String 'strの右側更新
Dim Str2 As String 'strの左側更新
Dim Str20 As String 'strの左側一部保存
Dim L As Long
Dim M As Long
Dim N As Long
Str1 = ActiveCell.Text
L = Len(Str1)
Debug.Print L
If L = 0 Then
End
End If
For N = 1 To L
Debug.Print Str2
Str0 = Left(Str1, 1)
If Str0 = X Or N = L Then
If Str20 <> "" Then
If N = L Then
Str20 = Str20 + Str0
End If
If MsgBox(Str20 & " はチェックしますか?", vbYesNo, "選択肢") = vbYes Then
Str2 = Str2 + Replace(Str20, X, Y)
Str20 = Str0
Else
Str2 = Str2 + Replace(Str20, Y, X)
Str20 = Str0
End If
Else
Str20 = Str0
End If
Else
Str20 = Str20 + Str0
End If
Str1 = Right(Str1, L - N)
Next N
ActiveCell.Value = Str2
End Sub
Sub sCheckXY(X As String, Y As String)
'選択セルがXならY,YならXにチェックをかえる
If ActiveCell.Text = X Then
ActiveCell.Value = Y
End
ElseIf ActiveCell.Text = Y Then
ActiveCell.Value = X
End
End If
End Sub
Sub sCheckX1234(X1 As String, X2 As String, X3 As String, X4 As String)
'選択セルがXならY,YならXにチェックをかえる
If ActiveCell.Text = X1 Then
ActiveCell.Value = X2
End
ElseIf ActiveCell.Text = X2 Then
ActiveCell.Value = X3
End
ElseIf ActiveCell.Text = X3 Then
ActiveCell.Value = X4
End
ElseIf ActiveCell.Text = X4 Then
ActiveCell.Value = X1
End
End If
End Sub
エラー発生で強制終了になってしまいます。2007年のexcelで作成したものですが、2010だと強制終了になってしまいます。
内容は□をダブルクリックすると■になるように作っています。
記述は2003年からのマクロ記述なので、変化が必要なのでしょうか?
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
'Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'セルをダブルクリックすると、・→○→△→×→・と変更する。
Dim S1 As String
Dim S2 As String
Dim S01 As String
Dim S02 As String
Dim S03 As String
Dim S04 As String
S1 = "□"
S2 = "■"
S01 = "・"
S02 = "○"
S03 = "△"
S04 = "×"
On Error GoTo ERR_12
sCheckXY S1, S2
sCheckX1234 S01, S02, S03, S04
sChangeXY S1, S2
Exit Sub
ERR_12:
End
End Sub
Sub sChangeXY(X As String, Y As String)
'選択セルに□があれば■に変える
Dim Str0 As String 'str1の左端
Dim Str1 As String 'strの右側更新
Dim Str2 As String 'strの左側更新
Dim Str20 As String 'strの左側一部保存
Dim L As Long
Dim M As Long
Dim N As Long
Str1 = ActiveCell.Text
L = Len(Str1)
Debug.Print L
If L = 0 Then
End
End If
For N = 1 To L
Debug.Print Str2
Str0 = Left(Str1, 1)
If Str0 = X Or N = L Then
If Str20 <> "" Then
If N = L Then
Str20 = Str20 + Str0
End If
If MsgBox(Str20 & " はチェックしますか?", vbYesNo, "選択肢") = vbYes Then
Str2 = Str2 + Replace(Str20, X, Y)
Str20 = Str0
Else
Str2 = Str2 + Replace(Str20, Y, X)
Str20 = Str0
End If
Else
Str20 = Str0
End If
Else
Str20 = Str20 + Str0
End If
Str1 = Right(Str1, L - N)
Next N
ActiveCell.Value = Str2
End Sub
Sub sCheckXY(X As String, Y As String)
'選択セルがXならY,YならXにチェックをかえる
If ActiveCell.Text = X Then
ActiveCell.Value = Y
End
ElseIf ActiveCell.Text = Y Then
ActiveCell.Value = X
End
End If
End Sub
Sub sCheckX1234(X1 As String, X2 As String, X3 As String, X4 As String)
'選択セルがXならY,YならXにチェックをかえる
If ActiveCell.Text = X1 Then
ActiveCell.Value = X2
End
ElseIf ActiveCell.Text = X2 Then
ActiveCell.Value = X3
End
ElseIf ActiveCell.Text = X3 Then
ActiveCell.Value = X4
End
ElseIf ActiveCell.Text = X4 Then
ActiveCell.Value = X1
End
End If
End Sub
当方XP&Office2003です。
Sub test()
Dim i As Long
For i = 1 To 200
Debug.Print i
Next i
End Sub
を実行すると、
2
3
・
・
・
200
と、表示され、最初の1が消えてしまいます。
イミディエイトウインドウでは、199行までしか表示できないのでしょうか?
私がoffice2003だからですか?
当方XP&Office2003です。
Sub test()
Dim i As Long
For i = 1 To 200
Debug.Print i
Next i
End Sub
を実行すると、
2
3
・
・
・
200
と、表示され、最初の1が消えてしまいます。
イミディエイトウインドウでは、199行までしか表示できないのでしょうか?
私がoffice2003だからですか?
エクセル フォーム上の全てのコントロールを取得したい
http://okwave.jp/qa/q4879853.html
のNo.1さんの回答を参考に、
Sub try()
Dim i As Integer
Dim StrFormName As String
StrFormName = "フォーム1"
For i = 0 To Forms(StrFormName).Controls.Count - 1
Debug.Print Forms(StrFormName).Controls.Item(i).Name
Next
End Sub
を作ったのですが、
「Forms」の部分が、
「Sub、Function、または Property が定義されていません。(Error 35)」
というコンパイルエラーになってしまいます。
上記のコードをアクセスVBAにつけると、全てのコントロール名が取得できます。
同じようにエクセルで使うにはどこを修正すればいいでしょうか?
フォーム名は、変数に入れて使いたいです。