[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『行挿入時実行時エラー1004が出ます回避方法は有りますでしょうか』(Ia)
以前このサイトで投稿されていましたVBAを使用させて頂いていますが
どちらも,行を挿入しますと実行時エラー(デバッグ)が出ます。
回避方法が有れば教えて頂けませんでしょうか。
マクロ初心者です。宜しくお願いします。<m(__)m>
Private Sub Worksheet_Change(ByVal Target As Range) Dim r As Range If Intersect(Target, Columns(11)) Is Nothing Then Exit Sub Application.EnableEvents = False For Each r In Intersect(Target, Columns(11)) If r.Row > 1 Then With r.Resize(, r(, Columns.Count - 10).End(xlToLeft).Column - 10) .Offset(, 1).Value = .Value End With End If Next Application.EnableEvents = True End Sub
AOption Explicit
Private Sub Worksheet_Change(ByVal Target As Range) Dim lc As Long Dim trgrow As Long Dim buf As Variant
If Application.Intersect(Target, Range("e:e")) Is Nothing Then Exit Sub End If ' ここに、項目の入力されている行を超えた場合処理中止のifがあったほうが良い Application.EnableEvents = False If Target.Value <> "" Then trgrow = Target.Row lc = Cells(trgrow, Columns.Count).End(xlToLeft).Column If lc >= 2 Then '(NN)が修正←過去の点検記録が無い場合 buf = Range(Cells(trgrow, 2), Cells(trgrow, lc)) Range(Cells(trgrow, 5), Cells(trgrow, lc + 3)).Value = buf Range("e" & trgrow).Value = "" '(NN)が追加←B列入力後空欄にする Range("d" & trgrow).Value = "" '(NN)が追加←B列入力後空欄にする Range("c" & trgrow).Value = "" '(NN)が追加←B列入力後空欄にする End If End If Application.EnableEvents = True If Application.Intersect(Target, Range("c:c")) Is Nothing Then Exit Sub End If ' ここに、項目の入力されている行を超えた場合処理中止のifがあったほうが良い Application.EnableEvents = False If Target.Value <> "" Then trgrow = Target.Row lc = Cells(trgrow, Columns.Count).End(xlToLeft).Column If lc >= 2 Then '(NN)が修正←過去の点検記録が無い場合 buf = Range(Cells(trgrow, 2), Cells(trgrow, lc)) Range(Cells(trgrow, 6), Cells(trgrow, lc + 4)).Value = buf End If End If Application.EnableEvents = True If Application.Intersect(Target, Range("b:b")) Is Nothing Then Exit Sub End If ' ここに、項目の入力されている行を超えた場合処理中止のifがあったほうが良い Application.EnableEvents = False If Target.Value <> "" Then trgrow = Target.Row lc = Cells(trgrow, Columns.Count).End(xlToLeft).Column If lc >= 2 Then '(NN)が修正←過去の点検記録が無い場合 buf = Range(Cells(trgrow, 2), Cells(trgrow, lc)) Range(Cells(trgrow, 7), Cells(trgrow, lc + 5)).Value = buf End If End If Application.EnableEvents = True End Sub また,一つ教えて頂きたいのですがO列に入力するとQ列の同じ行に同じ日付が入る VBAがあれば教えて頂けませんでしょうか,関数で処理はできるのですが, 処理が終わればQ列に入力する必要が有ります。その都度関数を入力するのは効率が悪いので、 値だけの移動と,行挿入時にエラーが出ないように出来ますでしょうか
< 使用 Excel:Excel2010、使用 OS:Windows7 >
>また,一つ教えて頂きたいのですがO列に入力するとQ列の同じ行に同じ日付が入る
>VBAがあれば教えて頂けませんでしょうか
>値だけの移動
値のコピーなのか、移動なのか明確にしましょう。
(もこな2) 2018/04/06(金) 20:43
>そもそも提示したマクロの動きは理解されてますか?
(コードを読むことができますか?) 正直マクロの動きは理解できていません。<m(__)m> >値のコピーなのか、移動なのか明確にしましょう。 B列 O列 P列 Q列 項目 入荷日 品質 ○店入荷日 リンゴ 4/6 A 4/6 みかん 4/5 B 完売 イチゴ 4/1 C 4/1 かき 4/2 A 返却 O列と同じ値がQ列に入力されるといいのです。 分りにくい質問で申し訳ありません。宜しくお願いします。 (Ia) 2018/04/06(金) 21:08
さて本題です。
ご提示のコードのうち
Worksheet_Change ←ここに注目です。
これは、ワークシートイベントの一つChangeイベントであることを意味します。
動きとしては、セルの値が変更されたときに発生します。
(※値そのものが入力されたときや消去されたときに発生。)
なので、「O列に入力するとQ列の同じ行に同じ日付が入る」であれば
変更のあったセル(範囲)にO列に含まれるものがあったら、Q列の同じ行に
同じ値を入れればよいってことになりますよね。
コードにするとこんな感じです。
Private Sub Worksheet_Change(ByVal Target As Range) Dim buf As Range, MyRNG As Range
Stop '←実行上は要らない。ブレークポイントの代わり
'セルの値を変更したセル(範囲)とO列が重複する範囲を求めて「buf」に格納 Set buf = Intersect(Target, Columns("O"))
'bufがNothingでない(つまり、変更したセル範囲にO列のものが含まれている)場合だけ実行 If Not buf Is Nothing Then '「buf」に格納したセル(範囲)から「MyRNG」に一つずつ取り出して処理 For Each MyRNG In buf Cells(MyRNG.Row, "Q").Value = MyRNG.Value Next MyRNG End If
End Sub
これをステップ実行して実際にどうなるか、変数に何が格納されているかを
確認してみてください。
そして、上記のコードが理解できるようになったら、提示したコードが
何をやっているのかもう一度考えてみてください。
ちなみに、エラーにも種類があるので、質問される場合はどのようなエラーが
出ているのかも伝えたほうがよいです。回答者側で状況が掴みやすくなります。
(もこな2) 2018/04/06(金) 23:21
>これをステップ実行して ~~~~~~~~~~~~
とお伝えしたつもりですが・・・・・
(もこな2) 2018/04/07(土) 06:59
私は作成依頼はお受けしない方針なのでここで降ります。
他の回答者?をお待ちください。
(もこな2) 2018/04/07(土) 08:20
>どちらも,行を挿入しますと実行時エラー(デバッグ)が出ます。
>Private Sub Worksheet_Change(ByVal Target As Range) の行にブレークポイントを設定して (参考URL>>http://www.ken3.org/vba/excel-help.html) ウォッチ式をTarget.Address(0,0)とr.Address(0, 0)と設定しておいて、 (参考URL>>https://www.vba-ie.net/debug/watch.html)
行を挿入してみると、
イベントが発生したときに、変数「Target」にその行のセル範囲が代入されるようです。
そのセル範囲からrが求められてますが、
r(, Columns.Count - 10).End(xlToLeft).Column
で、データ最終列を求めていると思いますが、
当然空白なのでEnd(xlToLeft)で1列目の1が返ってきます。
それから無条件に-10してますので、マイナスの値で
セル範囲をリサイズしようとしてますが、マイナスのセル範囲って存在しないですよね?
なので、実行時にそれが解ったので実行時エラーとなります。
ちなみに、実行前に文法がおかしくないかチェックされますが、
おかしければ、コンパイルエラーとなります。
なぜそういう風に書いたかわかりませんが、
言い回しがすごく遠回り(そういう風にしか表現できない場合もあるでしょうが)なので、
解りずらいです。
もっと簡単に表現したらいいと思います。
まずは日本語でやりたいことを明確にしてはいかがでしょう?
で、それをVBA語ではどう表現するのかを調べたり聞いたりしてはいかがでしょうか?
(まっつわん) 2018/04/07(土) 09:40
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngEvent As Range 'イベント処理をする対象セル範囲 Dim rngTarget2 As Range '操作対象セル範囲
'O列の1行目を除くセル範囲 With Me.Columns("O") Set rngEvent = .reize(, .Rows.Count - 1).Offset(1) End With
'値の変更があった場合、対象のセル範囲と重なるセル範囲を操作対象として取得 Set rngTarget2 = Intersect(Target, rngEvent) '重なるセルが無ければ処理を抜ける If rngTarget2 Is Nothing Then Exit Sub
'イベント処理の無効化(マクロでセルに入力する際はイベント処理を止める) Application.EnableEvents = False '2列右に転記 rngTarget2.Offset(, 2).Value = rngTarget2.Value 'イベント処理の有効化 Application.EnableEvents = True End Sub
これなら、短いコードの方も応用して書き換えられるのでは?
長い方のコード。
何をやりたいか解らないので、
どう対応していいかわからない。
手っ取り早く判定するなら、
一番最初に、
「Targetに渡されたセル範囲の全部セルが空白なら(行挿入と判定して)処理を抜ける」
とでも記述したらいいように思いますが、そんなんでいいか
やりたいことが解ってないのでなんとも。。。。。。
>その都度関数を入力するのは効率が悪いので、
>値だけの移動と,行挿入時にエラーが出ないように出来ますでしょうか
すごーく簡単に考えていると思いますが、
エクセルの標準機能にない機能をカスタマイズして追加しようとしてるのですよ。
操作者は、どんな操作をするか解らないです。
つまり、想定外の操作でプログラムが止まったり、
デバッグの画面が出ないようにプログラムを作ったり、メンテナンス出来る必要があります。
当然、困ったらこういう場所で相談するのもありでしょうが、
自分でメンテナンスをする気概がなければ、マクロを使わない方が良いです。
Iaさんは単に、
1個1個のセルに単に入力する場合しか想定してなかったのですよね?
コードはある程度複数セルをコピペした場合も想定されているように感じます。
ただ、「間違ったセル範囲に貼りつけてしまった。」というようなことは
想定されて無いような気がします。
まぁ、万が一にもコピペなんかしない。
たまにデバッグ画面が出てもきにしない。
ということならそれでもいいかもしれませんが、
僕ならこんな操作はマクロ化するより、
エクセルの手動の操作に慣れろって思います。
なぜなら、
1つ目の理由:
マクロを実行すると、元に戻すの履歴が消えて元に戻せなくなるからです。
2つ目の理由:
マクロを設定してあるファイルしか使えなくなるので、
いつまでたってもエクセルが使えないのは操作者にとって損。
慣れたらどんどんいろんなことをエクセルでして欲しいですよね?
3つ目の理由:
Windowsやエクセルは3〜4年ごとにバージョンアップしてます。
パソコンの買い替えやなんやらで、
いずれ使えなくなったりメンテナンスしなければいけない状況が出てくるかもしれない。
ソフトが動かない=仕事が出来ない
という状況が出てこない保証がない。
その時に早急に対応できるの????
と、まぁ大げさに言うとそういう状況が出てきます。
遊びの延長でマクロを扱うのもありですが、
そもそも同じ値を2回入れるのにどれくらい不便なんだろうって思ってます
O列のセルに行って、数値をテンキーで入れる、
Enterキーじゃなくて、左手でTABキー2回押して右手でテンキーでまた数値入力
ここでEnterキー押下で次の行
としたらよいと思います。
他にもショートカットキーで調べたらいろいろ便利なキー操作があるので、
そちらを覚えた方が得策かなぁとは思います。
まぁ、元凶は
.End(xlToLeft)
だろうからそれを使わない表現でセルの位置を表現できるようになればいいと思います。
(まっつわん) 2018/04/07(土) 10:33
(Ia) 2018/04/07(土) 11:10
申し訳ないとおっしゃっておられますが、別に怒っても責めてもいませんので気にしないでください。
わたしはまっつわんさんと違ってものぐさなので、マクロ作ってちょっとでも楽するっていうのは賛成なんです。
ただ、よくわからないマクロをそのまま”使える”との思いこみだけで実行してしまうと、マクロの作成者が善意であっても想定外の動作をさせることにつながりますし、マクロの作成者が悪意を持っている場合、マクロを使って深刻なダメージを与えることもできてしまいますから、いまのままで大丈夫かな〜って勝手に心配してるだけです。
たとえば、以下のマクロを「Thisworkbook」と書かれているモジュールに張り付けてみると楽しいですよ^^
なんて言われたら実行してしまうのではないでしょうか?(この程度であれば実害はないですが・・・)
Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range) Application.EnableEvents = False Target.Clear Application.EnableEvents = True End Sub
なので、素性のわからない人が作ったマクロを実行するのであれば、がんばってどのような動きをするものであるのか理解をしたうえで実行することを強くお勧めします。
そして、その過程で分からない部分があれば、その都度調べたりすればよいですし、どうしてもわからなければその部分をこのような質問サイトで聞いてみればいいとおもいます。
ちなみに、O列に入力があったら、Q列に同じ値を書き込むだけでよければ、
Stop '←実行上は要らない。ブレークポイントの代わり
って書いた部分を削除すれば止まらずに動くと思いますよ。
ステップ実行して研究してほしかったので意図的に止まるようにしただけなので・・・
(もこな2) 2018/04/07(土) 13:07
(Ia) 2018/04/07(土) 14:37
「マクロ作ってちょっとでも楽するっていうのは賛成」っていうのは、そういう考え方は好きですよって言いたかっただけなんです。たとえ手動操作よりすご〜く回りくどくなってしまっても、それはそれで本人に経験値として蓄積されるので、将来同じ問題に直面した時に、マクロ、手動どちらのアプローチがいいのか見極める力がつくと思うんですよね。
要は、『成功するための失敗なら、それは必要な失敗である』みたいな・・・
まっつわんさんの考え方がおかしいというつもりはなかったので、気分を害されてしまったのであれば申し訳ないです。
「以下のマクロを「Thisworkbook」と書かれているモジュールに張り付けてみると楽しいですよ 」
こちらは、なんでも盲目的に信じるとよろしくないコードも実行してしまう恐れがありますよといことをお伝えしたかったんです。
ちなみに、そのコードをブックモジュールにはりつけると、ブック内のどのシートのどのセルに入力しても、すぐにセルの書式を含めてクリアされるという迷惑なコードになっていますので、どうしても試すのであれば新規ブックに張り付けてくださいね。
(もこな2) 2018/04/07(土) 16:18
(Ia) 2018/04/08(日) 08:56
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.