Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


3109 / 13646 ツリー ←次へ | 前へ→

【64139】教えて下さい。 らいち 10/1/21(木) 19:49 質問[未読]
【64143】Re:教えて下さい。 kanabun 10/1/21(木) 21:49 発言[未読]
【64144】Re:教えて下さい。 UO3 10/1/21(木) 21:50 回答[未読]
【64145】Re:教えて下さい。 UO3 10/1/21(木) 21:55 発言[未読]
【64146】Re:教えて下さい。 たつや 10/1/21(木) 21:59 回答[未読]
【64147】Re:教えて下さい。 UO3 10/1/21(木) 22:28 発言[未読]
【64148】Re:教えて下さい。 たつや 10/1/22(金) 7:19 回答[未読]
【64149】Re:教えて下さい。 らいち 10/1/22(金) 8:58 お礼[未読]
【64155】Re:教えて下さい。 n 10/1/22(金) 11:30 発言[未読]
【64169】Re:教えて下さい。 らいち 10/1/22(金) 18:14 質問[未読]
【64170】Re:教えて下さい。 n 10/1/22(金) 22:16 発言[未読]
【64171】Re:教えて下さい。 たつや 10/1/23(土) 0:43 発言[未読]
【64173】Re:教えて下さい。 たつや 10/1/23(土) 1:06 発言[未読]
【64174】Re:教えて下さい。 n 10/1/23(土) 1:20 発言[未読]
【64175】Re:教えて下さい。 たつや 10/1/23(土) 1:46 発言[未読]
【64176】Re:教えて下さい。 たつや 10/1/23(土) 1:58 発言[未読]
【64214】Re:教えて下さい。 らいち 10/1/26(火) 15:46 発言[未読]
【64223】Re:教えて下さい。 n 10/1/26(火) 20:08 発言[未読]
【64225】Re:教えて下さい。 らいち 10/1/27(水) 9:29 お礼[未読]

【64139】教えて下さい。
質問  らいち  - 10/1/21(木) 19:49 -

引用なし
パスワード
   Z列が空欄の場合はその右隣のAA列も空欄に、
Z列に値が入ると、AA列に
"-"(ハイフン)を表示するVBAを組みたいのですが
どうしたらよろしいでしょうか。
Z列の範囲はZ5:Z3000です。

また上記の条件で複数列の設定をしたいです。

Z列に該当する列:Z列、AB列、AD列、AH列、AJ列、AL列
AA列に該当する列:AA列、AC列、AE列、AI列、AK列、AM列

が各々該当するように組みたいです。

よろしくお願いします。

【64143】Re:教えて下さい。
発言  kanabun  - 10/1/21(木) 21:49 -

引用なし
パスワード
   ▼らいち さん:

>Z列が空欄の場合はその右隣のAA列も空欄に、
>Z列に値が入ると、AA列に
>"-"(ハイフン)を表示するVBAを組みたいのですが
>どうしたらよろしいでしょうか。

数式ではだめですか?
よければ、[AA5]に数式で 左隣の[Z5]が空白なら""、
値があれば"-" を返すIF関数式をセットする操作をマクロ記録
してみるといいです。
>
>Z列に該当する列:Z列、AB列、AD列、AH列、AJ列、AL列
>AA列に該当する列:AA列、AC列、AE列、AI列、AK列、AM列

Sub Try1()
 With [Z5:Z3000].Offset(, 1).Columns
   Union(.Item(1), .Item(3), .Item(5), _
      .Item(9), .Item(11), .Item(13)) _
      .FormulaR1C1 = "=IF(RC[-1]="""","""",""-"")"
 End With
End Sub

【64144】Re:教えて下さい。
回答  UO3  - 10/1/21(木) 21:50 -

引用なし
パスワード
   ▼らいち さん:

 この処理でしたらVBAを使わず、セルに関数を書かれれば
 よしいかと思いますが、列数と行数が多いので面倒だという
 ことでしたら、すごく原始的なコードとしては以下のような
 感じ?でも処理時間が長いですよ。きっとエキスパートさんたちが
 もっと素敵なコードを紹介してくると思います。

Sub test()
Dim i As Long
Dim j As Long

 For i = 5 To 3000
 
  For j = 26 To 36 Step 2
  
   If Cells(i, j) = "" Then
    Cells(i, j + 1) = ""
   Else
    Cells(i, j + 1) = "-"
   End If
   
  Next
  
 Next
 
End Sub

【64145】Re:教えて下さい。
発言  UO3  - 10/1/21(木) 21:55 -

引用なし
パスワード
   ▼らいち さん:

kanabunさんのコードとUO3のものをためしてみてください。
UO3の処理は、いらいらするくらい長いんですが、kanabunさんの
コードは一瞬で処理が終わります。

=>kanabunさん

 さすがですね!

【64146】Re:教えて下さい。
回答  たつや  - 10/1/21(木) 21:59 -

引用なし
パスワード
   質問者さんにVBAの知識がないのであれば、マクロを使わないで関数で
AA5のセルに =IF(Z5="","","-")のように入力して、
該当するセルに数式を全部コピーするのが一番無難だと思います。

どうしてもVBAで動的にやりたいのであれば、以下のようになると思います。

Private Sub Worksheet_Change(ByVal Target As Range)

  Select Case Target.Column
    Case 26, 28, 30, 34, 36, 38:
    Case Else: Exit Sub
  End Select
  If Target.Row < 5 Then Exit Sub
  If Target.Row > 30000 Then Exit Sub
    If Target.Value <> "" Then Target.Offset(0, 1) = "-"
    If Target.Value = "" Then Target.Offset(0, 1) = ""
End Sub

【64147】Re:教えて下さい。
発言  UO3  - 10/1/21(木) 22:28 -

引用なし
パスワード
   らいちさん

 らいちさんのトピでオジャマムシのようにでしゃばって
 ごめんなさい。
 UO3がアップした、オバカというかマヌケというか、そんな
 コード以前に、そもそも、おやりになりたかったことは
 入力した【時に】結果が現れるというテーマでしたね。

 問題認識能力も最低レベルで、ただただ恥じ入っています。

==>kanabunさん、たつやさん

 コードももちろんですが課題を的確に把握される。
 う〜ん、すばらしいです。

【64148】Re:教えて下さい。
回答  たつや  - 10/1/22(金) 7:19 -

引用なし
パスワード
   すみません。
自分の回答は、一度にセル範囲をクリアしようとするとエラーがでますね。
ちょっと原因が分からないので、On Error Resume Nextで暫定的に回避しておきます。どなたか根本的な原因が分かる人がいたら、フォローお願いします。

Private Sub Worksheet_Change(ByVal Target As Range)

  Select Case Target.Column
    Case 26, 28, 30, 34, 36, 38:
    Case Else: Exit Sub
  End Select
  If Target.Row < 5 Then Exit Sub
  If Target.Row > 30000 Then Exit Sub
  On Error Resume Next
    If Target.Value <> "" Then Target.Offset(0, 1) = "-"
    If Target.Value = "" Then Target.Offset(0, 1) = ""
  On Error GoTo 0
End Sub

【64149】Re:教えて下さい。
お礼  らいち  - 10/1/22(金) 8:58 -

引用なし
パスワード
   kanabunさん、UO3さん、たつやさん

VBA初心者の私にでも
懇切丁寧に教えて頂き、有難う御座います。
早速やってみます。

セルに直接、関数を入れてやってみましたが
容量が大きくなるので、VBAでなんとか出来れば
と思い、ご相談しました。

他にも、後ほどご質問をさせて頂きたいので
もう少し、おつきあい願います。

【64155】Re:教えて下さい。
発言  n  - 10/1/22(金) 11:30 -

引用なし
パスワード
   ▼たつや さん:

複数セル範囲の変化時、Worksheet_Changeには複数セル範囲が渡されます。

Sub test()
  Range("A1:A2").Value = 1
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)
  Debug.Print Target.Address
End Sub

この場合のTargetは複数セル範囲。
>If Target.Value <> "" Then
これは
If Range("A1:A2").Value <> "" Then
などと書いている事と同じになります。
あるいは
Dim v As Variant
v = Range("A1:A2").Value
If v <> "" Then

Range("A1:A2").Valueは配列です。
If 配列 <> "" Then
という配列に対する <>"" 評価はできないですね?

Dim r As Range
For Each r In Target

といった感じでTargetの個々に対して処理する必要があります。

Application.EnableEvents = False/True
の制御も入れておいたほうが良いでしょう。

【64169】Re:教えて下さい。
質問  らいち  - 10/1/22(金) 18:14 -

引用なし
パスワード
   nさん、今回も有難う御座います。

たつやさんのコードのご指摘内容を修正すると
どのようなコードになりますでしょうか。
まったくの初心者ですいません。

【64170】Re:教えて下さい。
発言  n  - 10/1/22(金) 22:16 -

引用なし
パスワード
   ベースになるコードが出てるわけですから
チャレンジしてみて、自分なりに修正してみたものを投稿してみてください。、

あと、摘要範囲の判定にはIntersect メソッドを使ったほうが良さそうです。

【64171】Re:教えて下さい。
発言  たつや  - 10/1/23(土) 0:43 -

引用なし
パスワード
   nさん

確かに言われてみれば、複数範囲を渡していましたね。初心者丸出しなミスですみません。
本当は自分でデバッグすればよかったのですが、朝エラーが出ることに気づいて時間がなかったので。フォローありがとうございます。

ご指摘を踏まえて自分で組んでみましたが、確かに今のままだと、for eachから脱出するために、キーとなる変数をもうひとつ追加せざるを得ませんでした(gotoは使わない前提で)。
教えていただいたIntersectメソッドを使うことで、もっと単純に組めそうですね。

私としても、非常に勉強になりました。重ねて御礼申し上げます。

【64173】Re:教えて下さい。
発言  たつや  - 10/1/23(土) 1:06 -

引用なし
パスワード
   nさんへ 追伸

Intersectメソッドでも組んでみました。
非常に単純化されていい感じです。

なお、Nothingを返すかどうかでイベントを判断する関係上、特定の値をコピーして有効な範囲とそうでない範囲にまたがって貼り付ける(たとえばZ4からZ5、あるいはY10からZ10)場合には正常な結果は得られませんでしたが、このような使い方は基本的に想定されていないので許容範囲と判断しました。

【64174】Re:教えて下さい。
発言  n  - 10/1/23(土) 1:20 -

引用なし
パスワード
   >なお、Nothingを返すかどうかでイベントを判断する関係上、特定の値をコピーして有効な範囲とそうでない範囲にまたがって貼り付ける(たとえばZ4からZ5、あるいはY10からZ10)場合には正常な結果は得られませんでしたが、...
いやそんな事はないですよ。
Intersectメソッドをちゃんと使えば『Z4からZ5』がTargetの時、Nothingにはなりません。
もうちょっと悩んでみてください。

【64175】Re:教えて下さい。
発言  たつや  - 10/1/23(土) 1:46 -

引用なし
パスワード
   >Intersectメソッドをちゃんと使えば『Z4からZ5』がTargetの時、Nothingにはなりません。
>もうちょっと悩んでみてください。

いえ、Nothingが帰ってくるという意味ではなくて、Nothingではない(つまり範囲が帰ってくる)ことでイベントをスタートさせているため、たとえば値をコピーして『Z4からZ5』に貼り付けると、本来は『AA5』だけに「−」が入力されるべきところを、『AA4からAA5』に「−」が入力されてしまう結果になっています。これを単純に回避する方法はありますでしょうか?

ここからさらに場合分けをするのであれば、Intersectメソッドを使うメリットがあまり感じられないような気もするのですが…

【64176】Re:教えて下さい。
発言  たつや  - 10/1/23(土) 1:58 -

引用なし
パスワード
   nさん

すみません。自己解決しました。
いったんIf Not … Is Nothing Then で判定するところまではよかったのですが、
そのあとTargetの範囲を使うのではなく、
For Each r In Intersect(Target, Range("Z5:Z3000"))
のようにすればよかったのですね。

たびたびお付き合いいただいてありがとうございました。

【64214】Re:教えて下さい。
発言  らいち  - 10/1/26(火) 15:46 -

引用なし
パスワード
   ▼n さん:
>ベースになるコードが出てるわけですから
>チャレンジしてみて、自分なりに修正してみたものを投稿してみてください。、
>
>あと、摘要範囲の判定にはIntersect メソッドを使ったほうが良さそうです。

これで大丈夫でしょうか。一応機能しました。
範囲指定が多いので、Range()内が長くなってしまいますが、どうしたら
よろしいでしょうか。

Private Sub Worksheet_Change(ByVal Target As Range)
  If Intersect(Target, Range("Z5:Z3000,AB5:AB3000,AD5:AD3000")) Is Nothing Then Exit Sub
  Application.EnableEvents = False
    If Target.Value <> "" Then Target.Offset(0, 1) = "-"
    If Target.Value = "" Then Target.Offset(0, 1) = ""
  Application.EnableEvents = True
End Sub

【64223】Re:教えて下さい。
発言  n  - 10/1/26(火) 20:08 -

引用なし
パスワード
   >範囲指定が多いので、Range()内が長くなってしまいますが、どうしたら...
基本的には、折り返して記述すれば良いと思います。

あとはTargetが複数範囲だった時の対応を入れないといけませんね。

Private Sub Worksheet_Change(ByVal Target As Range)
  Dim rng As Range
  Dim r  As Range

  Set rng = Intersect(Target, Rows("5:3000"), _
            Range("Z:Z,AB:AB,AD:AD,AH:AH,AJ:AJ,AL:AL"))
  If Not rng Is Nothing Then
    Application.EnableEvents = False
    For Each r In rng
      If r.Value <> "" Then
        r.Offset(, 1).Value = "-"
      Else
        'r.Offset(, 1).Value = ""
        r.Offset(, 1).ClearContents 'で可?
      End If
    Next
    Application.EnableEvents = True
    Set rng = Nothing
  End If
End Sub

【64225】Re:教えて下さい。
お礼  らいち  - 10/1/27(水) 9:29 -

引用なし
パスワード
   nさん、本当にありがとうございました。

もうひとつ、解決できないことが出てきました
ので教えて頂きたいのですが、今回までの質問と
主旨が異なるので、新規投稿させてください。

3109 / 13646 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free