No.5ベストアンサー
- 回答日時:
No2です。
シート名に対する回答がないので、現在表示されているシートに対して操作を行います。このマクロと無関係のシートを表示した状態で、このマクロを実行するとそのシートが破壊されますので
注意ください。
こちらの環境では、約10万件で8秒で終わっています。
以下のマクロを標準モジュールへ登録してください。
------------------------------------------------------------
Option Explicit
Public Sub 相殺()
Const delm As String = "|"
Dim maxrow As Long
Dim row As Long
Dim dicM1 As Object '連想配列 マイナス側(キー=日付+金額+商品コード)値=最大件数
Dim dicM2 As Object '連想配列 マイナス側(キー=日付+金額+商品コード+連番)値=行番号
Dim dicP As Object '連想配列 プラス側(キー=日付+金額+商品コード)値=処理件数
Dim key1 As String
Dim key2 As String
Dim t1 As Variant
Dim t2 As Variant
t1 = Time
Set dicM1 = CreateObject("Scripting.Dictionary") ' 連想配列の定義
Set dicM2 = CreateObject("Scripting.Dictionary") ' 連想配列の定義
Set dicP = CreateObject("Scripting.Dictionary") ' 連想配列の定義
Application.ScreenUpdating = False
maxrow = Cells(Rows.Count, 1).End(xlUp).row '最大行取得
Range("J2:J" & maxrow).Value = ""
Range("K2:K" & maxrow).Value = ""
'マイナス側のデータを集計
For row = 2 To maxrow
'マイナス側なら連想配列に登録
If Cells(row, "H").Value = 1 Then
key1 = Cells(row, "C").Value & delm & Cells(row, "D").Value & delm & Cells(row, "E").Value
If dicM1.exists(key1) = True Then
dicM1(key1) = dicM1(key1) + 1
Else
dicM1(key1) = 1
End If
key2 = key1 & delm & dicM1(key1)
dicM2(key2) = row
End If
Next
'プラス側のデータを処理
For row = 2 To maxrow
'プラス側なら処理
If Cells(row, "H").Value = 0 Then
key1 = Cells(row, "C").Value & delm & Cells(row, "D").Value & delm & Cells(row, "E").Value
If dicM1.exists(key1) = True Then
If dicP.exists(key1) = True Then
dicP(key1) = dicP(key1) + 1
Else
dicP(key1) = 1
End If
'マイナス側の最大件数以内なら相殺フラグをON
If dicM1(key1) >= dicP(key1) Then
Cells(row, "J").Value = 1 'プラス側相殺
key2 = key1 & delm & dicP(key1)
Cells(dicM2(key2), "K").Value = "1" 'マイナス側相殺
End If
End If
End If
Next
Application.ScreenUpdating = True
t2 = Time
MsgBox ("終了しました Time=" & Minute(t2 - t1) & "分" & Second(t2 - t1) & "秒")
End Sub
---------------------------------------------------
申しわけございません。
同じ回答者さんだと思ってスルーしていました。
ご回答ありがとうございます。
教えていただいたコードでテストしまして
うまくいきました。時間も早かったです。
No.6
- 回答日時:
時間に関してですが全比較で合っていたら次の項目を比較なのでどうしても時間がかかります。
比較するものを事前にソートしておくと比較しなければいけない部分が減りますので10分の1以下にはなりそうです(もちろん比較方法を変えないといけませんけど)。元に戻せば良いというならば、使っていない列に元の行番号を入れて、処理後にそれでソートしてその列をクリアしてしまえば何もなかったようにも出来ます。L列あたりを使っても良いですか?No.4
- 回答日時:
とりあえず一部だけ説明しておきます。
-----------------------------------------------------------------------
多分ですが、配列に代入されたときにどうなるかが判りにくいと思います。
たとえば「d = Range("D2:G20")」または「d = Range(Cells(2, 4), Cells(20, 7))」の場合
「Range("D2")」(左上)の値は「d(1, 1)」に入ります。
「Range("G2")」(右上)の値は「d(1, 4)」に入ります。
「Range("D20")」(左下)の値は「d(19, 1)」に入ります。
「Range("G20")」(右下)の値は「d(19, 4)」に入ります。
感じとしては代入すると、A1セルを選択した所にコピーされたようになるだけです。
※ タイトル行を抜いたので判りにくかったかも知れません。
-----------------------------------------------------------------------
符号がプラス(0)に対してマイナス(1)のもので同じものがあったら
・符号を別なもの(-1)にして次回対象にならないようにする。(s(m, 1) = -1)
・符号がプラスの行の「判定1」の列にフラグ(1)を代入します。(f(p, 1) = 1)
・符号がマイナスの行の「判定2」の列にフラグ(1)を代入します。(f(m, 2) = 1)
・マイナスのループを抜ける。(Exit For)
-----------------------------------------------------------------------
No.3
- 回答日時:
データが多いので配列を使ってみました。
-----------------------------------------------------------------------------
Sub Sample()
Dim d As Variant
Dim s As Variant
Dim f As Variant
Dim e As Long
Dim p As Long
Dim m As Long
e = Cells(Rows.Count, 1).End(xlUp).Row
Range(Cells(2, 10), Cells(e, 11)).ClearContents
d = Range(Cells(2, 2), Cells(e, 5))
s = Range(Cells(2, 8), Cells(e, 8))
f = Range(Cells(2, 10), Cells(e, 11))
For p = 1 To e - 1
If s(p, 1) = 0 Then
For m = 1 To e - 1
If s(m, 1) = 1 Then
If d(p, 1) = d(m, 1) Then
If d(p, 2) = d(m, 2) Then
If d(p, 3) = d(m, 3) Then
If d(p, 4) = d(m, 4) Then
s(m, 1) = -1
f(p, 1) = 1
f(m, 2) = 1
Exit For
End If
End If
End If
End If
End If
Next
End If
Next
Range(Cells(2, 10), Cells(e, 11)) = f
MsgBox ("終了しました")
End Sub
-----------------------------------------------------------------------------
※ ソートをかけて良ければさらに早く出来ると思います。
ありがとうございました。
充分に早くできます。10万桁でも30秒ほどで終わりました。
ある程度理解できるのですが、当方の環境にあわすため
中身を少し教えていただけませんか?
For p = 1 To e - 1
If s(p, 1) = 0 Then
For m = 1 To e - 1
If s(m, 1) = 1 Then
If d(p, 1) = d(m, 1) Then
If d(p, 2) = d(m, 2) Then
If d(p, 3) = d(m, 3) Then
If d(p, 4) = d(m, 4) Then
s(m, 1) = -1
f(p, 1) = 1
f(m, 2) = 1
Exit For
このあたり
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) Excel(VBA) 特定の条件に該当する行の値、書式を同じセルにコピ&ペーストしたいです 1 2022/05/21 18:18
- Visual Basic(VBA) VBA初心者です。電話番号の数字の前に0を表示させたいです。 2 2022/12/14 03:58
- Visual Basic(VBA) エクセルVBA コードが同じでもファイルによって処理速度が大きく変わるのはなぜ 5 2022/11/06 21:34
- その他(データベース) 4進数風なバーコードは何ですか? 2 2022/11/28 23:33
- その他(Microsoft Office) エクセルで1行の長いデータを指定の桁数で分割する方法が知りたいです。 4 2022/05/20 21:55
- Perl Perlで特定文字列から特定文字列までを抜き出したい 4 2022/04/02 14:24
- Java Javaについて質問です。 勉強し始めたばかりの初心者です。 相続税について課税額を算出するコードを 1 2022/05/31 19:02
- Excel(エクセル) Excel ある複数列に数値を入力した際に、別の列に本日の日付を入力したいです 7 2023/03/01 23:31
- Visual Basic(VBA) tatsumaru77様 昨日回答して頂いたものです。 すみませんが、昨日の質問で1つ補足があります 1 2022/05/15 15:06
- Excel(エクセル) 【Excel】指定のセル内容を基に別シートのセルを検索して選択する【VBA】 1 2022/06/16 16:16
このQ&Aを見た人はこんなQ&Aも見ています
-
性格の違いは生まれた順番で決まる?長男長女・中間子・末っ子・一人っ子の性格の傾向
同じ環境で生まれ育っても、生まれ順で性格は違うものなのだろうか。家庭教育研究家の田宮由美さんに教えてもらった。
-
VBAで処理フラグの立て方
Visual Basic(VBA)
-
フラグについて
Visual Basic(VBA)
-
フラグをたてるってどういうことですか?
Excel(エクセル)
-
-
4
エクセルVBAで5行目からオートフィルタモードに設定したいたい
Excel(エクセル)
-
5
access クエリでIIF文で抽出条件なし
Access(アクセス)
-
6
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
-
7
フラグを立てた物のみを別シートへ反映したい
Excel(エクセル)
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
首吊りどこ締めるの
-
勃起する時って痛いんですか? ...
-
検便についてです。 便は取れた...
-
彼女のことが好きすぎて彼女の...
-
白血球が多いとどんな心配があ...
-
これって喉仏ですか? 私は女性...
-
精子が黄色?
-
中出しをするとお腹が痛い・・・。
-
風俗店へ行く前のご飯
-
腕を見たら黄色くなってる部分...
-
精子に血が・・・
-
甲状腺が腫れているが血液検査...
-
エクセル指定した範囲からラン...
-
至急!尿検査前日にオナニーし...
-
便潜血検査(検便)で柔らかい...
-
納豆食べた後の尿の納豆臭は何故?
-
筋トレするとチンコが縮んじゃ...
-
舌の裏の痛みのないプツプツの...
-
EXCELで式からグラフを描くには?
-
精液の落とし方を教えてください
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
首吊りどこ締めるの
-
至急!尿検査前日にオナニーし...
-
白血球が多いとどんな心配があ...
-
尿検査前日に自慰行為した時の...
-
検便についてです。 便は取れた...
-
彼女のことが好きすぎて彼女の...
-
腕を見たら黄色くなってる部分...
-
勃起する時って痛いんですか? ...
-
尿検査の前日は自慰控えたほう...
-
精子が黄色?
-
中出しをするとお腹が痛い・・・。
-
EXCELで条件付き書式で空白セル...
-
口の中に黒い血の塊
-
これって喉仏ですか? 私は女性...
-
2つの数値のうち、数値が小さい...
-
納豆食べた後の尿の納豆臭は何故?
-
EXCELで式からグラフを描くには?
-
小数点以下を繰り上げたものを...
-
excelでsin二乗のやり方を教え...
-
エクセル指定した範囲からラン...
おすすめ情報
伝票番号は変わることもありますので、同じでなくてもいいです。
すみません。検証したのは10000桁でした。
当方の環境で10万桁で検証しますと、30分程
かかりました。