Excel VBA質問箱 IV

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

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


1175 / 13645 ツリー ←次へ | 前へ→

【75860】Range object をFunctionに引渡す処理について Aoba 14/7/19(土) 11:37 質問[未読]
【75861】Re:Range object をFunctionに引渡す処理に... マナ 14/7/19(土) 12:02 発言[未読]
【75862】Re:Range object をFunctionに引渡す処理に... Aoba 14/7/19(土) 12:36 質問[未読]
【75863】Re:Range object をFunctionに引渡す処理に... マナ 14/7/19(土) 13:22 発言[未読]
【75867】Re:Range object をFunctionに引渡す処理に... kanabun 14/7/19(土) 20:31 質問[未読]
【75871】Re:Range object をFunctionに引渡す処理に... Aoba 14/7/20(日) 9:51 お礼[未読]
【75872】Re:Range object をFunctionに引渡す処理に... マナ 14/7/20(日) 10:08 発言[未読]
【75873】Re:Range object をFunctionに引渡す処理に... マナ 14/7/20(日) 10:13 発言[未読]
【75874】Re:Range object をFunctionに引渡す処理に... Aoba 14/7/20(日) 11:48 お礼[未読]

【75860】Range object をFunctionに引渡す処理に...
質問  Aoba  - 14/7/19(土) 11:37 -

引用なし
パスワード
   Range object(変数 Rng) をFunctionに引渡す場合以下のようにしましたが
引渡されていません。原因がわかりません
宜しくお願いします

Sub Comb入力()
  Dim LastRow As Long
  Dim Retu As Integer
  Dim Rng As Range
 
  Set sht = Workbooks("Bookname.xls").Worksheets("Sheet1")
  Set Rng = Range("E4", Range("E65536").End(xlUp))
  sht.Activate
   Retu = 5
   LastRow = Cells(65536, Retu).End(xlUp).Row
   sht.Cells(LastRow + 1, Retu) ="2020
   Comb sht, Rng, Retu

End Sub

Function Comb(sht As Worksheet, Rng As Range, Retu As Integer)
   Dim jyufuku As Integer
   Dim i As Integer
   
   For i = Cells(65536, Retu).End(xlUp).Row To 4 Step -1
      jyufuku = WorksheetFunction.CountIf(Rng, Cells(i, Retu).Value)
      If jyufuku > 1 Then
        sht.Cells(i, Retu).Select
        Selection.Delete Shift:=xlUp
      End If
   Next i
End Function

Functionで
jyufuku = WorksheetFunction.CountIf(Rng, Cells(i, Retu).Value)
を以下のようにしますと上手く処理できます
jyufuku = WorksheetFunction.CountIf(Range("E4", Range("E65536").End(xlUp)), Cells(i, Retu).Value)

【75861】Re:Range object をFunctionに引渡す処理...
発言  マナ  - 14/7/19(土) 12:02 -

引用なし
パスワード
   とりあえず、activateしない、selectしないことを意識して
書きなおしてみてはどうでしょうか

【75862】Re:Range object をFunctionに引渡す処理...
質問  Aoba  - 14/7/19(土) 12:36 -

引用なし
パスワード
   ▼マナ さん:
>とりあえず、activateしない、selectしないことを意識して
>書きなおしてみてはどうでしょうか

sht.Activate をしないとゆうことでしょうか
これではどのSheetがActiveになっているかどうか
不明でうまくいきませんでした
ご回答の意味がよくわかりません
よろしくお願いいたします

【75863】Re:Range object をFunctionに引渡す処理...
発言  マナ  - 14/7/19(土) 13:22 -

引用なし
パスワード
   >sht.Activate をしないとゆうことでしょうか

そうです。

>これではどのSheetがActiveになっているかどうか
>不明でうまくいきませんでした

どのSheetがActiveになっていても同じ動作するようにするためには
対象シートを明確に記述すればよいです。

例えば、↓の場合どのシートが対象になるかあいまいです。

>  Set Rng = Range("E4", Range("E65536").End(xlUp))

一方、↓これは、対象シートがshtであることが明確です。

>        sht.Cells(i, Retu).Select

この点を気をつけて全体を見なおせば、とりあえず期待の動きをすると思います。
(コードに無駄な部分が多いような気がしますが)

【75867】Re:Range object をFunctionに引渡す処理...
質問  kanabun  - 14/7/19(土) 20:31 -

引用なし
パスワード
   よこから 失礼します。
以下は、マナ さんがすでにおっしゃってることですが


---------
▼Aoba さん:
> sht.Activate をしないとゆうことでしょうか
> これではどのSheetがActiveになっているかどうか
> 不明でうまくいきません

それはエクセルにとっても同じです。

>  Set sht = Workbooks("Bookname.xls").Worksheets("Sheet1")
>  Set Rng = Range("E4", Range("E65536").End(xlUp))
>  sht.Activate

この1行目は shtという変数に あるブック内の"Sheet1"という名のシートを
指定していますから、shtがどのBookのシートか 明示されています。

ところが、2行目は
> Range("E4", Range("E65536").End(xlUp))
となっていて、どのシートのRange("E4") か どのシートの Range("E65536")
か? 明示されてません。
シートが明示されてないと、エクセルは ActiveSheet が省略されているのだと
と解釈します。

なので、
>  Set Rng = Range("E4", Range("E65536").End(xlUp))
は、
そのときアクティブになっているシートが
Workbooks("Bookname.xls").Worksheets("Sheet1")
すなわち sht でなかったら、Rngは 別のシートの
Range("E4", Range("E65536").End(xlUp))
がセットされていることになります。

[E4]セルというのは どのシートにもあるセルの名前なので、
仮にいま アクティブなシートが sht でなくても、このコードは
"エラーになってくれません"。
なので、ご質問のようなバグ状況が発生するのです。
あなたは shtをアクティブにしたつもりでも、それは Rngをセットしてあと
のことなので、Rngの親シートが sht であることは保障されていないのです!

2行目で sht の E列範囲を 変数Rng にセットしたいのなら、

(sht をアクティブにしてから、
 Set Rng = Range("E4", Range("E65536").End(xlUp)) 
とする方法もあるにはありますが...)

sht をアクティブにしなくても、

 Set Rng = sht.Range("E4", sht.Range("E65536").End(xlUp))

とシートを明示しておけば、済むことなのです。

【75871】Re:Range object をFunctionに引渡す処理...
お礼  Aoba  - 14/7/20(日) 9:51 -

引用なし
パスワード
   ▼kanabun さん マナさん:
お手数をお掛けしました。有難うございました

1)sht をアクティブにしてから、
 Set Rng = Range("E4", Range("E65536").End(xlUp))
  にしましたら上手くいきました。
 
2)sht をアクティブにしないで、
  'sht.Activate
   Set Rng = sht.Range("E4", sht.Range("E65536").End(xlUp))
   にしましたらRngが引渡されていませんでした。

  取敢えず今のところこれで解決しました
  2)については再度調べてみます
  わからないときはまたお願いいたします

【75872】Re:Range object をFunctionに引渡す処理...
発言  マナ  - 14/7/20(日) 10:08 -

引用なし
パスワード
   ▼Aoba さん: 
>2)sht をアクティブにしないで、
>  'sht.Activate
>    Set Rng = sht.Range("E4", sht.Range("E65536").End(xlUp))
>   にしましたらRngが引渡されていませんでした。

sht をアクティブにしない場合は、
すべてのrangeオブジェクトについてシート指定することが必要です。
そんな面倒なと思うかもしれませんが、
今回の場合は、おそらく "Sheet1"のみの操作なので問題が少ないですが、
複数シートを扱うようなマクロだと困ることがでてくるでしょう。

なので、アクティブにしない方法も、理解することをお勧めします。

【75873】Re:Range object をFunctionに引渡す処理...
発言  マナ  - 14/7/20(日) 10:13 -

引用なし
パスワード
   ついでに、質問の件と違うところについて。

Rngは"Sheet1"のE列ですよね
つまり、Rngは、shtとRetuに関する情報を持っているので

>Function Comb(sht As Worksheet, Rng As Range, Retu As Integer)

は、

Function Comb(Rng As Range)

でも大丈夫なはず。
修正してみました。例えば、こんな感じで。

Function Comb(Rng As Range)
  Dim jyufuku As Integer
  Dim i As Integer
   
  For i = Rng.Count To 2 Step -1
    '2020についてはダブリの心配なし?
    jyufuku = WorksheetFunction.CountIf(Rng, Rng(i).Value)
    If jyufuku > 1 Then
      Rng(i).Delete Shift:=xlUp
    End If
  Next

End Function


そうすると、Sub Comb入力()の方は、
これだけでもよい気がします。

Sub Comb入力()
  Dim Rng As Range
  Const Retu = "E"

  With Workbooks("Bookname.xls").Worksheets("Sheet1")
    Set Rng = .Range(.Cells(4, Retu), .Cells(65536, Retu).End(xlUp))
  End With
  Rng(Rng.Count + 1).Value = 2020
  Comb Rng

End Sub

で、こうすると、Rngにセットする際に、シート指定しているだけですが、
あとは、すべてRngを使っているので、どのシートがactiveかを気にする必要もなくなります。

【75874】Re:Range object をFunctionに引渡す処理...
お礼  Aoba  - 14/7/20(日) 11:48 -

引用なし
パスワード
   ▼マナ さん:
ご丁寧なアドバイス有難うございます
今回はE列のみでしたが他の列がある場合
についてもトライしてみます
また、アドバイスお願いいたします

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