- ベストアンサー
マクロの記録で作成したマクロがデータが代わると誤動作する
- マクロの記録で作成したマクロがデータの変更によって誤動作する場合、正確なデータの処理方法やエラーチェックを実装する必要があります。
- 特に、エクセルファイルにてデータを置換えたり行を並べ替えたりする場合は、データの変更に対応できる柔軟な処理が求められます。
- マクロ記録中にセル番号を指定する方法ではなく、条件に基づいて処理を行うマクロを記録すべきです。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
>ただ教えていただいた記述で試した所 >--略-- >でA列が出庫だったらその行のJ列を切り取りL列に貼り付けが >出来なくてJ列に残っています。 >記述を見てもどこが原因かわかりませんでした。 マクロの問題ではありません。こちらの解釈と食い違いがあるからです。 1>>B列が3で受入に置換えたら >> 2>>その隣のA列の値を受入に置き換えたい。 >>さらに 3>>A列の値が置換え後の ↑ここは、「B列で3で受入に置き換えたら」とつながっていると解釈しました。 だから、B列で、「3=受入」というものがあって、成立するものと解釈しています。 そうでないものは無視されています。単に、A列が、入庫、戻入、出庫なら変化しません。 A列とB列の関係は、単に、B列の「受入」がある時、A列の同じ行を「受入」に直すものだけだったのしょうか。 '// Sub ReplacingPrc1() Dim i As Long Dim Ar1 As Variant, Ar2 As Variant Dim LastRow As Long Ar1 = Array("", "入庫", "出庫", "戻入") Ar2 = Array("", "社内品", "リール", "受入") Application.ScreenUpdating = False LastRow = Cells(Rows.Count, 1).End(xlUp).Row For i = 1 To LastRow If IsNumeric(Cells(i, 1).Value) Then If Cells(i, 1).Value > 0 And Cells(i, 1).Value < 4 Then Cells(i, 1).Value = Ar1(Cells(i, 1).Value) End If End If Next For i = 1 To LastRow If IsNumeric(Cells(i, 2).Value) Then If Cells(i, 2).Value > 0 And Cells(i, 2).Value < 3 Then Cells(i, 2).Value = Ar2(Cells(i, 2).Value) ElseIf Cells(i, 2).Value = 3 Then Cells(i, 2).Value = Ar2(Cells(i, 2).Value) Cells(i, 1).Value = Cells(i, 2).Value End If End If If Cells(i, 10).Value <> "" Then 'J列--二度処理防止 If Cells(i, 1).Value Like "入庫" Or Cells(i, 1).Value Like "戻入" Then Cells(i, 11).Value = Cells(i, 10).Value: Cells(i, 10).ClearContents ElseIf Cells(i, 1).Value Like "出庫" Then Cells(i, 12).Value = Cells(i, 10).Value: Cells(i, 10).ClearContents End If End If Next Application.ScreenUpdating = False End Sub
その他の回答 (5)
- Wendy02
- ベストアンサー率57% (3570/6232)
あまりよく分かっていないかもしれませんが、少し書き換えてみました。 これは、理屈では作っていません。読んだままにしていますから、読み違えているかもしれません。1部#3の記録マクロを参考にしました。 '//標準モジュール Sub ReplacingPrc() Dim i As Long Dim Ar1 As Variant, Ar2 As Variant Dim LastRow As Long Ar1 = Array("", "入庫", "出庫", "戻入") Ar2 = Array("", "通常品", "リール", "受入") Application.ScreenUpdating = False LastRow = Cells(Rows.Count, 1).End(xlUp).Row For i = 1 To LastRow If IsNumeric(Cells(i, 1).Value) Then If Cells(i, 1).Value > 0 And Cells(i, 1).Value < 4 Then Cells(i, 1).Value = Ar1(Cells(i, 1).Value) End If End If Next For i = 1 To LastRow If IsNumeric(Cells(i, 2).Value) Then If Cells(i, 2).Value > 0 And Cells(i, 2).Value < 3 Then Cells(i, 2).Value = Ar2(Cells(i, 2).Value) ElseIf Cells(i, 2).Value = 3 Then If Cells(i, 1).Value = "入庫" Or Cells(i, 1).Value = "戻入" Then Cells(i, 11).Value = Cells(i, 10).Value: Cells(i, 10).ClearContents ElseIf Cells(i, 1).Value = "出庫" Then Cells(i, 12).Value = Cells(i, 10).Value: Cells(i, 10).ClearContents End If Cells(i, 2).Value = Ar2(Cells(i, 2).Value) End If End If Next Application.ScreenUpdating = False End Sub
お礼
わざわざありがとうございます。 これなら私の分よりはるかに短いですね。 うごきました。 ただ教えていただいた記述で試した所 >A列が入庫、戻入だったらその行のJ列を切り取りK列に貼り付け >A列が出庫だったらその行のJ列を切り取りL列に貼り付け >A列が受入だったらその行のJ列はそのまま >です。 でA列が出庫だったらその行のJ列を切り取りL列に貼り付けが 出来なくてJ列に残っています。 記述を見てもどこが原因かわかりませんでした。
- layy
- ベストアンサー率23% (292/1222)
A列やB列、コード体系を名称に置換してますが、JKL列の操作はコードのままの判定でもできるのではないでしょうか。整理してみてください。 B列が3のときA列再置換としてますが、B列は受入に置換した後では?。 A列受入になるのはB列受入のとき、最終的にA列は4パターンB列は3パターンありますね。 そのA列とB列の組み合わせ値がどうなっているかを判定するかなので、あとは自分で必要な箇所、JKL列の操作直前にIF文追記してください。マクロの記録は一連の操作記録ですからここまでしません。 名称にするのは後まわしでもいいのでは?。
お礼
ありがとうございます。 >B列が3のときA列再置換としてますが、B列は受入に置換した後では?。 はい。そうしました。 長文で困ってます。 'A列の値を置換 Columns("A:A").Select Selection.Replace What:="1", Replacement:="入庫", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Columns("A:A").Select Selection.Replace What:="2", Replacement:="出庫", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Selection.Replace What:="3", Replacement:="戻入", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False 'B列の値を置換 Columns("B:B").Select Selection.Replace What:="1", Replacement:="社内品", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Columns("B:B").Select Selection.Replace What:="2", Replacement:="社外品", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Selection.Replace What:="3", Replacement:="受入", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Range("A1").Select 'B列の値が受入ならA列も受入に変更 行 = 2 Do While Cells(行, 2).Value <> "" If Cells(行, 2).Value = "受入" Then Cells(行, 1).Value = "受入" End If 行 = 行 + 1 Loop '作業が入庫、戻入なら入庫数へ出庫なら出庫数へ 行 = 2 Do While Cells(行, 1).Value <> "" If Cells(行, 1).Value = "入庫" Then Cells(行, 10).Select Application.CutCopyMode = False Selection.Cut Cells(行, 11).Select ActiveSheet.Paste End If 行 = 行 + 1 Loop 行 = 2 Do While Cells(行, 1).Value <> "" If Cells(行, 1).Value = "戻入" Then Cells(行, 10).Select Application.CutCopyMode = False Selection.Cut Cells(行, 11).Select ActiveSheet.Paste End If 行 = 行 + 1 Loop 行 = 2 Do While Cells(行, 1).Value <> "" If Cells(行, 1).Value = "出庫" Then Cells(行, 10).Select Application.CutCopyMode = False Selection.Cut Cells(行, 12).Select ActiveSheet.Paste End If 行 = 行 + 1 Loop
- hoiho1111
- ベストアンサー率16% (10/59)
??? ますますわかりませんね 1と入庫の関係は 置換前の文字="1" 置換後の文字="入庫" でしょうか? それがなぜ "受入" に変わるのですか? いずれにしても マクロの記録では汎用性がありません VBEで直接コードを書くほうがいいでしょう 1例ですが Sub 置換() Dim C As String For Eacu C In Selection C.value=Replace(C.value,"1","入庫") Next End If End sub
お礼
ありがとうございました。 なんとかできましたが長文です。 'A列の値を置換 Columns("A:A").Select Selection.Replace What:="1", Replacement:="入庫", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Columns("A:A").Select Selection.Replace What:="2", Replacement:="出庫", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Selection.Replace What:="3", Replacement:="戻入", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False 'B列の値を置換 Columns("B:B").Select Selection.Replace What:="1", Replacement:="通常品", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Columns("B:B").Select Selection.Replace What:="2", Replacement:="リール", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Selection.Replace What:="3", Replacement:="受入", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Range("A1").Select 'B列の値が受入ならA列も受入に変更 行 = 2 Do While Cells(行, 2).Value <> "" If Cells(行, 2).Value = "受入" Then Cells(行, 1).Value = "受入" End If 行 = 行 + 1 Loop '作業が入庫、戻入なら入庫数へ出庫なら出庫数へ 行 = 2 Do While Cells(行, 1).Value <> "" If Cells(行, 1).Value = "入庫" Then Cells(行, 10).Select Application.CutCopyMode = False Selection.Cut Cells(行, 11).Select ActiveSheet.Paste End If 行 = 行 + 1 Loop 行 = 2 Do While Cells(行, 1).Value <> "" If Cells(行, 1).Value = "戻入" Then Cells(行, 10).Select Application.CutCopyMode = False Selection.Cut Cells(行, 11).Select ActiveSheet.Paste End If 行 = 行 + 1 Loop 行 = 2 Do While Cells(行, 1).Value <> "" If Cells(行, 1).Value = "出庫" Then Cells(行, 10).Select Application.CutCopyMode = False Selection.Cut Cells(行, 12).Select ActiveSheet.Paste End If 行 = 行 + 1 Loop
補足
申し訳ありません。 A列には1か2か3の文字しかありません。 これではわからないので、 1→入庫 2→出庫 3→戻入 とエクセル上での表示を変えます。 :セルA1に1と入力されていたらセルA1を 入庫 と入力します。 次にB列ですがここにも1か2か3の文字しかしかありません。 同じように 1→社内品 2→社外品 3→受入 と変更します。 でB列が変更前の3でも変更後の受入であっても その場合のその行のA列には 入庫、出庫、戻入ではなく、受入と表示をしたいのです。 で A列が入庫、戻入だったらその行のJ列を切り取りK列に貼り付け A列が出庫だったらその行のJ列を切り取りL列に貼り付け A列が受入だったらその行のJ列はそのまま です。
- akina_line
- ベストアンサー率34% (1124/3287)
こんにちは。 >A列の値が置換え後の入庫と戻入場合はその行のJ列の値を切り取り、K列に貼付をし A列の値が置換え後の出庫の場合はその行のJ列の値を切り取り、L列に貼付をしたいです。 これは本来、マクロのIF文を使わないと実現できない処理です。自動記録では、あなた自身が「A列の値が置換え後の入庫と戻入場合はX行からY行までだ」と判断して操作をしているのだと思いますが、その操作はマクロとして記録されても、その判断は記録できません。 マクロの自動記録はとても便利ですが、このように「条件分岐」や「繰り返し処理」などは自分でVBAの文法を理解して自動記録されたマクロを修正する必要があります。 では。
お礼
ありがとうございました。 なんとかできました。 ただこの記述で合っているかは不安ですが。 'B列の値が受入ならA列も受入に変更 行 = 2 Do While Cells(行, 2).Value <> "" If Cells(行, 2).Value = "受入" Then Cells(行, 1).Value = "受入" End If 行 = 行 + 1 Loop '作業が入庫、戻入なら入庫数へ出庫なら出庫数へ 行 = 2 Do While Cells(行, 1).Value <> "" If Cells(行, 1).Value = "入庫" Then Cells(行, 10).Select Application.CutCopyMode = False Selection.Cut Cells(行, 11).Select ActiveSheet.Paste End If 行 = 行 + 1 Loop 行 = 2 Do While Cells(行, 1).Value <> "" If Cells(行, 1).Value = "戻入" Then Cells(行, 10).Select Application.CutCopyMode = False Selection.Cut Cells(行, 11).Select ActiveSheet.Paste End If 行 = 行 + 1 Loop 行 = 2 Do While Cells(行, 1).Value <> "" If Cells(行, 1).Value = "出庫" Then Cells(行, 10).Select Application.CutCopyMode = False Selection.Cut Cells(行, 12).Select ActiveSheet.Paste End If 行 = 行 + 1 Loop
補足
やはりマクロの記録では無理なのですね。 ありがとうございます。 今、参考書見ながら苦戦しています。 ヒントはいただけますか? 'A列の値を置換 Columns("A:A").Select Selection.Replace What:="1", Replacement:="入庫", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Columns("A:A").Select Selection.Replace What:="2", Replacement:="出庫", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Selection.Replace What:="3", Replacement:="戻入", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False 'B列の値を置換 Columns("B:B").Select Selection.Replace What:="1", Replacement:="通常品", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Columns("B:B").Select Selection.Replace What:="2", Replacement:="リール", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Selection.Replace What:="3", Replacement:="受入", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _ ReplaceFormat:=False Range("A1").Select IF文にしたらA1のセルの値を置き換えると、無限ループしてしまいます。 あとB列が受入れの場合A列の値を受入に変換するのもマクロの記録では 無理でした。(判断が必要なので) それから、 >A列の値が置換え後の入庫と戻入場合はその行のJ列の値を切り取り、K列に貼付をし >A列の値が置換え後の出庫の場合はその行のJ列の値を切り取り、L列に貼付をしたいです。 このサンプルも参考書やWEB検索でも見つかりません。 どう作成すればいいのでしょうか?。 申し訳ありません。
- hoiho1111
- ベストアンサー率16% (10/59)
置換? 言ってる意味がよくわかりませんね 1=入庫の場合 これはどういう意味ですか? Range("a1")に"入庫"と入っているんですか?
お礼
ありがとうございます。
補足
すいません。 エクセルで 編集→置換 の機能で セルAを選択して 検索文字:1 置換文字:入庫 とすると A列にある全ての 1 は 受入 に置き換わります。 そういう意味です。 マクロの記録でそういう操作を記録しました。
お礼
>A列とB列の関係は、単に、B列の「受入」がある時、 >A列の同じ行を「受入」に直すものだけだったのしょうか。 はい。そうです。 基幹システムの設計仕様のミスでこうなってしまい、 (本来はA列が1,2,3,4でB列が1,2ですが、 A列が4に相当する場合はA列には1、B列に3と記録するにしてしまったのです。) 取り出したデータで直すしかない為、 B列が3の場合はA列を4(受入です)にするのです。 ありがとうございました。
補足
Sub ReplacingPrc1() Dim i As Long Dim Ar1 As Variant, Ar2 As Variant Dim LastRow As Long Ar1 = Array("", "入庫", "出庫", "戻入") Ar2 = Array("", "社内品", "リール", "受入") Application.ScreenUpdating = False LastRow = Cells(Rows.Count, 1).End(xlUp).Row For i = 1 To LastRow If IsNumeric(Cells(i, 1).Value) Then If Cells(i, 1).Value > 0 And Cells(i, 1).Value < 4 Then Cells(i, 1).Value = Ar1(Cells(i, 1).Value) End If End If Next For i = 1 To LastRow If IsNumeric(Cells(i, 2).Value) Then If Cells(i, 2).Value > 0 And Cells(i, 2).Value < 3 Then Cells(i, 2).Value = Ar2(Cells(i, 2).Value) ElseIf Cells(i, 2).Value = 3 Then Cells(i, 2).Value = Ar2(Cells(i, 2).Value) Cells(i, 1).Value = Cells(i, 2).Value End If End If If Cells(i, 10).Value <> "" Then 'J列--二度処理防止 If Cells(i, 1).Value Like "入庫" Or Cells(i, 1).Value Like "戻入" Then Cells(i, 11).Value = Cells(i, 10).Value: Cells(i, 10).ClearContents ElseIf Cells(i, 1).Value Like "出庫" Then Cells(i, 12).Value = Cells(i, 10).Value: Cells(i, 10).ClearContents End If End If Next Application.ScreenUpdating = False End Sub これで完璧に出来ました。 どうもありがとうございました。