[[20200827150044]] 『Rangeの中のCells』(k) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『Rangeの中のCells』(k)

Sub 請求書作成()

Dim rowsData As Long, rowsClient As Long
rowsData = wsData.Cells(Rows.Count, 1).End(xlUp).Row '請求データの最終行数
rowsClient = wsClient.Cells(Rows.Count, 1).End(xlUp).Row '取引先マスタの最終行数

'年月を入力ダイアログで入力
Dim dayCutoff As Date
dayCutoff = Application.InputBox("年月を入力してください", "対象年月を入力", Format(Date, "yyyy/mm"))

Dim n As Long
For n = 2 To rowsClient

    Dim client As String
    client = wsClient.Cells(n, 1).Value

    'ひな形ブックを開きそのシートとともにセットする
    Dim wb As Workbook, ws As Worksheet
    Set wb = Workbooks.Open(ThisWorkbook.Path & "\請求書ひな形.xlsx")
    Set ws = wb.Worksheets(1)

    '該当の取引先かつ年月のデータを転記する
    Dim i As Long, k As Long
    k = 21
    For i = 2 To rowsData

        If wsData.Cells(i, 2).Value = client Then
            Dim deliDate As Date
            deliDate = wsData.Cells(i, 1).Value

            If Year(deliDate) = Year(dayCutoff) And Month(deliDate) = Month(dayCutoff) Then
★               wsData.Range(wsData.Cells(i, 3), wsData.Cells(i, 5)).Copy ws.Cells(k, 1)
                k = k + 1
            End If
        End If
    Next i

    'その他の転記と行の非表示
    ws.Rows(k & ":50").Hidden = True  'データがない行を隠す

    ws.Range("A18").Value = "ご請求金額:" & Format(ws.Range("D54").Value, "#,##0") & " 円"
    ws.Range("A3").Value = client & "御中"  '取引先名
    ws.Range("A5").Value = "〒" & wsClient.Cells(n, 2).Value '郵便番号
    ws.Range("A6").Value = wsClient.Cells(n, 3).Value '住所1
    ws.Range("A7").Value = wsClient.Cells(n, 4).Value '住所2
    ws.Range("D15").Value = DateSerial(Year(dayCutoff), Month(dayCutoff) + 1, 0) '請求日
    ws.Range("D16").Value = DateSerial(Year(dayCutoff), Month(dayCutoff) + 2, 0) 'お支払期限

    'ファイル名を生成して保存して閉じる
    Dim fileName As String
    fileName = ThisWorkbook.Path & "\" & Format(dayCutoff, "yyyymm") & "請求書_" & client & ".xlsx"
    wb.SaveAs fileName
    wb.Close

Next n
End Sub

★の部分なのですが
★wsData.Range(wsData.Cells(i, 3), wsData.Cells(i, 5)).Copy ws.Cells(k, 1)

wsData.Range(Cells(i, 3), Cells(i, 5)).Copy ws.Cells(k, 1)
と書いたらエラーがでてしまいました。wsData.を入れないと動かないのはなぜでしょうか?宜しくお願い致します。

< 使用 Excel:Office365、使用 OS:Windows10 >


wsData.Range(ActiveSheet.Cells(i, 3), ActiveSheet.Cells(i, 5)).Copy ws.Cells(k, 1)
と書いたものと解釈され、wsDataとActiveSheetが異なる場合は、Excel君が立ち往生してしまうのです。

(γ) 2020/08/27(木) 15:59


じゃあ、
Range(wsData.Cells(i, 3), wsData.Cells(i, 5)).Copy ws.Cells(k, 1)
と書いたら、同じ理屈?でエラーになりそうなものだが、エラーにはならない(たぶん)。

どこまでも突き詰めたいなら、どなたが回答して下さるかもしれないが、
結局はそう決めたんだ、というところに落ち着くことになる。
なので、上の話は聞かなかったことにして、
ひとまず、2020/08/27(木) 15:59の回答で、
ああそうなのね、と鞘に収めるのが妥当なところかもしれません。
(γ) 2020/08/27(木) 16:07


 97のころは、
 Activesheet.range(Cells(1,1),Cells(3,3))
 でも、エラーになってましたから、指定するなら外も中も同じ物を指定するようにしました。
(BJ) 2020/08/27(木) 20:33

 あこっちか

 With Activesheet
     .range(Cells(1,1),Cells(3,3)).select
 End with
(BJ) 2020/08/27(木) 20:36

 >Range(wsData.Cells(i, 3), wsData.Cells(i, 5)).Copy ws.Cells(k, 1)
 >と書いたら、同じ理屈?でエラーになりそうなものだが、エラーにはならない(たぶん)。
 これがエラーにはならない理由は、
 Application.Range(wsData.Cells(i, 3), wsData.Cells(i, 5)).Copy ws.Cells(k, 1)
 だからですよね?
(´・ω・`) 2020/08/28(金) 09:17

´・ω・`さんのおっしゃるとおりです。ありがとうございました。
 
この話は、別のところでもよく議論になりますが、
じゃあ、 Range(wsData.Cells(i, 3), wsData.Cells(i, 5))と言う書き方が
余り使われないのはなぜか?などの論点があると思います。

(γ) 2020/08/29(土) 07:06


 >この話は、別のところでもよく議論になりますが、

 昔、私も余所でやったことがありますが、今でも腑に落ちない部分があります。

 通常、この解釈がまかり通っていますよね?
     | (Application.Rangeのヘルプにも書かれていることです。)
     ↓
 「オブジェクト修飾子を指定せずにRangeプロパティを使用すると、
  ActiveSheet.Range のショートカットとなります。」

 ところが、このタイプの時だけ、Applicationが省略された処理になるのは何故か?(その記述がどこにも見当たらない)
      ↓ 
 Range(cellオブジェクト, cellオブジェクト)

(半平太) 2020/08/29(土) 10:43


 そもそもそんな記述する機会がなかったのですが、

 >ところが、このタイプの時だけ、Applicationが省略された処理になるのは何故か?
 Range(ws.Cells)
 Range(ws.Range)
 Range(ws.Range, ws.Range)
 Range(変数, 変数)
 または↑の組合せ
 の場合はまた違った結果なんですかね?
 今日パソコンのないところにいるのでためせないんですが。
(稲葉) 2020/08/29(土) 11:52

 >オブジェクト修飾子を指定せずにRangeプロパティを使用するとActiveSheet.Range
 は、

 オブジェクト修飾子を指定せずにRange(Cells)プロパティを使用すると
 Application.Range(Cells) と解釈され、
 Application.Range(Cells) は ActiveSheet.Range(Cells) を返す。

 と2段階なんだとおもいます
(´・ω・`) 2020/08/29(土) 12:17

 稲葉さん
 > Range(ws.Cells)
 > Range(ws.Range)
 二つの違いがわからないです。
 そのまんまじゃないですよね?

 (´・ω・`)さん
 > オブジェクト修飾子を指定せずにRange(Cells)プロパティを使用すると
 > Application.Range(Cells) と解釈され、
 > Application.Range(Cells) は ActiveSheet.Range(Cells) を返す。

 「Cells」の部分を実際に動く記述で教えて頂けませんか?

(半平太) 2020/08/29(土) 14:23


>★wsData.Range(wsData.Cells(i, 3), wsData.Cells(i, 5))

↑こういう文章は饒舌だと思います。
質問も結局くどくどwsDataを何度も書きたくないということが発端だと思います。
で、省略した結果、記述に矛盾が出てきてエラーになる羽目に。
Application.Range(wsData.Cells(i, 3), wsData.Cells(i, 5))
僕は普段からこう書きます。
(というか、wsData.Cells(i, 3).resize(,3)こう書くかな。)

なぜなら、
そもそも、Cells等が返すRangeオブジェクトには、
そのセルが属するシートやブックの情報があるので、
1回「このセル範囲」と決めたら、あとは、「これ」というだけで、
そのセルが属するシートの話をしなくても話が通じるので、
「このセルからこのセルの範囲」というときは、シートの話をするのは無駄だし、
間違いのもとになるからです。
なので、セル範囲を変数に代入することを覚えることをお勧めします。

>rowsData = wsData.Cells(Rows.Count, 1).End(xlUp).Row

Rows.countはどのシートの行数を数えるか明示してないので、
エクセル君が勝手に判断することになります。

dim c as range
set c = Cells(Rows.Count, 1).End(xlUp)
msgbox c.worksheet.name
msgbox c.address(,,,true)

こんなことを試してみることをお勧めします。
あと、ステップインで実行しながらローカルウィンドウで、
変数cの中身を確認してみてください。
変数の左の「+」をクリックすることで中身を展開できます。
(「オブジェクト」というものの概念がもしかしたら理解できるかも)

この件に関しては様々な意見があると思いますし、
僕の説明も言葉が足らない部分もあるとは思います。
ぼくの意見が正しいというわけでもないけど、参考になれば。
(まっつわん) 2020/08/29(土) 16:20


 半平太さん
 ごめんなさい。書き方がわるかったです。

 オブジェクト修飾子を指定せずにRangeプロパティを使用すると
 Application.Range と解釈され、
 Application.Range は ActiveSheet.Range を返す。

 同様に

 オブジェクト修飾子を指定せずにCellsプロパティを使用すると
 Application.Cells と解釈され、
 Application.Cells は ActiveSheet.Cells を返す。

 です。
(´・ω・`) 2020/08/29(土) 17:16

 (´・ω・`)さん

 すみません。勘違いしました。m(__)m

 全て、Applicationが省略されていると考えるのが正しいですね。

 Activesheetが省略されているのと言って構わないケースが多いが、
 2つの引数がRangeオブジェクトの場合は、
 その2つがActivesheetのものじゃない限り、Activesheetの省略であるハズがない。

 ありがとうございました。

(半平太) 2020/08/29(土) 19:33


 なるほど!
 そこまでお節介やいてくれるなら
 Sheets(1).Range(cells(1, 1))
 こういうのはSheetsオブジェクトを省略しても通じてほしいですよね
(稲葉) 2020/08/29(土) 21:03

 (1)
 Excel.Global のメンバー
 Property Range(Cell1, [Cell2]) As Range
 (2)
 Excel.Application のメンバー
 Property Range(Cell1, [Cell2]) As Range
 (3)
 Excel.Worksheet のメンバー
 Property Range(Cell1, [Cell2]) As Range
 という少なくとも3つのRangeがありますね。(オブジェクトブラウザ参照)

 コードを、何の修飾もなく Rangeで始めた場合は、(1)が適用されます。
 Excel.rangeとか、Application.Rangeとかは(2)です。
 エラーになったというのは、無論(3)ですね。
 シートの食い違いが起きうるのは、(3)の時だけです。

 ■
 |  97のころは、
 |  Activesheet.range(Cells(1,1),Cells(3,3))
 |  でも、エラーになってましたから、指定するなら外も中も同じ物を指定するようにしました。
 私はそういう記憶がなかったですが、そうすると当初は、
 Range(ws.Cells(1,1),ws.Cells(3,3))という書き方が主で、
 その後、
 ws.Range(Cells(1,1),Cells(3,3))に移っていったのでしょうか(自信なし)。

 ■
 Range(ws.Cells(1,1),ws.Cells(3,3))を使っている方がおられましたが、
 少なくとも質問掲示板では余り多くない印象です。

 その理由についての私見ですが、
 Set R = Worksheets("Sheet1").Range("A1")
 というようにワークシートを頭につけて、修飾するのが分かり易いわけで、
 そうすると、それで統一したほうが可読性は高まるのではないか、という気持ちから、
 ws.Range(Cells(1,1),Cells(3,3))と書くことが一般的なのではないでしょうか。
 さらにエラー対応を考慮して、
 ws.Range(ws.Cells(1,1),ws.Cells(3,3))
 となったのではないか、と思います。

 # 稲葉さん、Range(Cells(1,1)) という書き方はそもそもエラーですよ。うっかりミスでしょうね。

(γ) 2020/08/29(土) 21:36


 γさん
 > コードを、何の修飾もなく Rangeで始めた場合は、(1)が適用されます。
 > Excel.rangeとか、Application.Rangeとかは(2)です。

 はー、そうなんですか。またまた分からなくなったです。 
 どこで差が出るんでしょうか?(無理にご返信は要らないですが)

 稲葉さん
  今回は、引数を2つ持つときの話がメインとなっています。 
  1つの時は、Range型は引数にできません。

  その時は、cells(1, 1)の標準プロパティが採用されることになるので、
  A1セルにアドレスを指定する文字(例えば「Z9」とか)が入って無い限り、エラーになります。
  たまたまエラーにならなかったとしても、期待する結果ではないと思います。

(半平太) 2020/08/29(土) 21:57


(1)と(2)は実質的には同様の機能と思います。
(グローバルというクラスで定義されていないものは、文頭からは使えないということですね。
 Rangeはグローバルの配下にあるので、頭からRangeと書き始めることができます。)
(3)は明確に他の2つとは違います。
 Rangeの頭にあるシートと、その引数に指定するものが持つシート情報と二つが違うことが起こりえます。
 
ひとつのRangeが多義的に解釈されるのではなく、明確に別のものであると考える必要があると思います。
# 間違っていたら失礼します。
(γ) 2020/08/29(土) 22:56

 >(1)と(2)は実質的には同様の機能と思います。
 >(グローバルというクラスで定義されていないものは、文頭からは使えないということですね。
 > Rangeはグローバルの配下にあるので、頭からRangeと書き始めることができます。)

 と言うことは(省略と言う言葉の問題かも知れませんが)、

 > Range(ws.Cells(1,1),ws.Cells(3,3))
 この書き方は、オブジェクト修飾子が省略されている訳ではないのでそのままでよく、

 Application.Range(ws.Cells(1,1),ws.Cells(3,3)) とわざわざ正規っぽく書く必要はないし、
      ws.Range(ws.Cells(1,1),ws.Cells(3,3)) と屋上屋を重ねる意味も「本来」ない。

 という理解でいいですかね。(無理にご返信は要らないですが)

 ただ、私の場合、2つの引数がRangeオブジェクトになることはそう多くないので
 通常は、こう書かざるを得ないことが多いです。(頭のws.がないと"A1"がActiveSheetのA1セルと解釈されるので)
      ↓ 
     ws.Range("A1",ws.Cells(3,3))

(半平太) 2020/08/30(日) 09:34


 前半に書かれた点は、私は自己流にそう考えていました。
 そう解釈しないと現実が説明つかないと思うのです。
 つまり、Application.Rangeのヘルプ(*)には、
 省略時はActivesheetと解釈すると書かれていますが、
 それだと、
 Range(ws.Cells(1,1),ws.Cells(3,3))
 としたときに、wsがアクティブシートでなければ、
 エラーにならないといけないと思うのですね。
 しかし、実際には有効に機能する、という現実があります。

 (私は、その記法を推奨しているわけではなく、既に書いたように、
   統一して、Rangeの頭にシートの指定をしたほうが一貫性はあるのかなと思っています。)

 後半の部分は、どう書くんでしょうか。
 まっつわんさんにお聞きしたいですが、
 Range(ws.Range("A1"),ws.Cells(3,3))
 と書くんでしょうか。

 (*)例文がWorksheet.Rangeのものであったりして、精度は余り高くない印象です。
    現実を説明できないところは、ユーザーとしては現実を認めていくしかないのかな、と。
(γ) 2020/08/30(日) 11:04

 > 後半の部分は、どう書くんでしょうか。

 あ、すみません。そこは悩んでないところです。それしかないと思っていますので。

 実際はこんな形で使っています。

  With ws
     Debug.Print .Range("A1", .Cells(.Rows.Count, "A").End(xlUp).Offset(, 3)).Address
  End With

(半平太) 2020/08/30(日) 12:00


質問者 k さんからの返信がないですね。
理解されたのでしょうかね。

(HAN) 2020/08/30(日) 12:39


 GlobalとApplicationの違いが何処かにありはしないかテストしていたら、
 コードを書く場所が、シートモジュールの場合、差が出ました。ご参考まで。

 このコードをWorksheets(2)に書くと、Globalはエラーになります。
  ↓
 Sub texOnSheet()
     Dim r1 As Range
     Dim r2 As Range

     Set r1 = ThisWorkbook.Worksheets(1).Range("B2")
     Set r2 = ThisWorkbook.Worksheets(1).Range("E4")

     Debug.Print Application.Range(r1, r2).Address  'OK
     Debug.Print Range(r1, r2).Address              'Error
 End Sub

(半平太) 2020/08/31(月) 08:33


 >後半の部分は、どう書くんでしょうか。
 >まっつわんさんにお聞きしたいですが、
 >Range(ws.Range("A1"),ws.Cells(3,3))
 >と書くんでしょうか。

そうです。

  >With ws
  >   Debug.Print .Range("A1", .Cells(.Rows.Count, "A").End(xlUp).Offset(, 3)).Address
  >End With

 with worksheets(1)
     debug.print application.range(.range("A1"),.cells(.rows.count,"A").end(xlup).offset(,3).address
 end with

こう書きます。
「application.range(・・・)と書くよ」と発言したら、別の掲示板でもちょっと叩かれましたが、
たくさんの自分の失敗と、たくさんの掲示板の質問と回答
(特に識者(γさんや半平太さんも含む)の考察)を見てきた中での、
現時点での自分なりの結論です。

「一貫性」っていうなら、

 >sheets("Sheet1").Range("Sheet1!$A$1", sheets("Sheet1").Cells(.Rows.Count, "A")
って書くのが筋では?と感じてます。

あと、
sheets(1).range(sheets(2).range("A1"),sheets(3).cells(3,"C").select
っても書いちゃったときに、
シートの整合性をチェックする箇所が3か所になります。
application.range(sheets(2).range("A1"),sheets(3).cells(3,"C").select
ならば、かっこの中1か所だけチェックしたら済むと思います。

というか、セル範囲に何かしたいときは、ワークシートを代入する変数は使いません。

 Option Explicit

 Sub test()
     Dim rngTop As Range
     Dim rngBottom As Range
     Dim rngTable As Range
     Dim r As Range

     With Worksheets(1)
         Set rngTop = .Range("A3")
         Set rngBottom = .Cells(.Rows.Count, "C").End(xlUp)
     End With
     Set rngTable = Application.Range(rngTop, rngBottom)

     For Each r In rngTable.Rows
         MsgBox r.cells(1).Address(False, False)
     Next

     With rngTable.Worksheet
         .Range("D10").Select
     End With
 End Sub

また、
Range(ws.Range("A1"),ws.Cells(3,3))
のように親オブジェクトを省略すれば、
見た目違和感ありありですし、
思いもよらぬ解釈をエクセル君にされる可能性を否定できないので、
明示する必要があるというのは、半平太さんの実験でも明らかです。

     Debug.Print Range(r1, r2).Address              'Error

は、

     Debug.Print Me.Range(r1, r2).Address            'Error
と解釈されるようですね。

kさんへ>>
回答は、ひとつの見解であり様々な意見があります。
なので、広く回答を募る中で自分で判断し取捨選択されるようにするといいと思います。
僕の意見は、異端のようなので、切り捨てても問題ないです。
が、
VBAのコードは様々な場面で省略して記述することが可能になっています。
知っていて省略するのと、知らないで「こういう時はこう書くんだ」と丸暗記しているのでは、
大きな違いがあります。
なので、こういう質問はすごく有意義だと思います。
どんどん、質問して見識を深めていってください^^
回答側も意見の交換が出来て大変有意義だったと思います^^
(こちらも、考えを言語化できて整理が出来ました^^)

参考になれば。
(まっつわん) 2020/08/31(月) 10:38


みなさんご回答ありがとうございます。
自分は初心者なので、みなさんの意見が深くて理解があまりできませんでした。
ご回答の中で、エクセルが勝手に省略されているとのことでしたので
wsData.Range(Cells(i, 3), Cells(i, 5))を省略しないで書くと
wsData.Range(Activesheet.Cells(i, 3), Activesheet.Cells(i, 5))とエクセルが理解して,
wsDataとActivesheetが違うから誤作動が起きるという事は理解できました。

誤作動の理解はできたのですが、
wsData.Rangeと最初に指定していると思うのですが、なぜRangeの中になるとActivesheetと、判断するのでしょうか?
回答は、全て読んだのですが、自分の理解力のなさで、この回答がすでに書かれていたらすみません。
(k) 2020/08/31(月) 11:47


 >wsData.Rangeと最初に指定していると思うのですが、
 >なぜRangeの中になるとActivesheetと、判断するのでしょうか?

 お気持ちは分かりますが、
 最初に指定したシートの効力が、カッコの中にまで及ぶのは、
 引数が「アドレス文字の場合」であり、

 カッコの中が「2つのRangeオブジェクトの場合」は、
 まず、そのオブジェクトを評価するという仕様になっているだけです。

 また、カッコの中に入ったからActiveSheetと判断した訳じゃなく、
 Cellsにシートの修飾子がないから一般則に従ってActiveSheet上と判断された訳です。

 ※もし、コードがシートモジュールに書かれたのであれば、
  そのSheet上と判断されます。アクティブであろうがなかろうが(念の為)

(半平太) 2020/08/31(月) 14:34


 # 半平太さんから適切なコメントがあり、ちょっと重複が生じてしまいましたが、そのまま投稿します。

 半平太さん ご指摘ありがとうございました。
 シートモジュール(というある種のクラスモジュール)でのふるまいは
 また別の要素が入ってくるのですね。勉強になります。

 まっつわんさん、コメントありがとうございました。
 生粋のapplication.range派であることが理解できました。

 # Range(ws.Range("A1"),ws.Cells(3,3))と書くと、頭のRangeのシート指定がないじゃないか、
 # と脊髄反射を起こしてしまいがちな人も多いかも知れませんね。
 # (これが統一性ということにつながるのかどうか)
 # また、
 # application.range(.range("A1"),.cells(.rows.count,"A")
 # といった書き方は、将棋で言う「敵の打ちたいところに打て」を想起させますね。
 # 予め、誤解が起きないように、application.rangeと書いておいて、入り込まないようにする
 # ということですか。単なる感想です。

 質問者さんへ:
 | wsData.Rangeと最初に指定していると思うのですが、なぜRangeの中になるとActivesheetと、判断するのでしょうか?

 ひとことで言えば、そのように決めた製品だから、ということでしょう。
 (また、より正確に言うと、シートモジュールの時は、Activesheetでなくそのシートと判断)

 Worksheet.Rangeの中で使用するRangeオブジェクトのワークシート帰属をどう定めるか、
 それは、質問者さんの考える方法もあり得たでしょう。
 そのほうが気が利いているとも思います。
 しかし、マイクロソフトはそうは考えなかった。
 色々な内部事情があるのかもしれません。
 結果として、現在のような仕組みを採用した、ということです。
 採用理由はマイクロソフト社にしか回答できないでしょう。

 くどいですが、これはユーザー側が論理で導き出せる話ではなく、
 そう決めたから、という話なので、
 ユーザーとしては、そういう振る舞いをすることを知って(このことが重要)、
 それを使いこなすことに注力するほかないと思われます。
 例えば、Withステートメントを使っていかに冗長度を低減するかとかの工夫も、
 「使いこなす」の中に含まれるでしょう。
(γ) 2020/08/31(月) 14:47

 >wsData.Rangeと最初に指定していると思うのですが、なぜRangeの中になるとActivesheetと、
 >判断するのでしょうか?
 >回答は、全て読んだのですが、自分の理解力のなさで、この回答がすでに書かれていたらすみません。

なぜと言われてもそういう風にExcelVBAが作られているとしか言いようがないかと。
使う側はその振る舞いを理解し使いこなすことしかできません。

Cells(1,1)と書いたら、
それは、何かのプロパティの括弧の中であっても、外であっても、
「アクティブシートの1行目の1列目」という意味になります。
それ以外の事はありません。
「(シートの修飾を)省略している」ということは、
読み手に(今回の場合はエクセル君)に解釈を任せるということなので、
書き手と読み手で齟齬が起きるかも知れないということは当然の事だと思います。

再度書きます。

>rowsData = wsData.Cells(Rows.Count, 1).End(xlUp).Row

rowsData = wsData.Cells(activesheet.Rows.Count, 1).End(xlUp).Row
の意味になります。
シートの行の数を数えるだけですので、どのシートで数えてもいいようなものですが、
同じエクセルのファイルでも、旧バージョンのシートの行数と新バージョンのシートの行数が
違う場合がありますので、エラーの温床になります。

rowsData = wsData.Cells(wsData.Rows.Count, 1).End(xlUp).Row
などと書いておいた方が今後バージョンアップでエクセルのシートの行数が変わっても、
戸惑うことが少ないと思います。
(まっつわん) 2020/08/31(月) 17:34


[[20200825081004]] 『VBAでActiveSheetを使い続けるリスク』(k) >>BOT
 こちらは解決されました?

 まずは途中で変な茶々入れたのでお詫びを・・・ To All
 申し訳ございませんでした。

 今回の疑問とは直接関係ないですが、色々なやり方あるよってことで、参考までに・・・
    Sub test1()
        Dim i As Long
        Dim ws As Worksheet
        Set ws = Sheets(1)
        Sheets.Add.Activate
        For i = 1 To 10
            Debug.Print ws.Range(Cells(i, "C").Address, Cells(i, "E").Address).Address & ":文字列"
            Debug.Print ws.Range(ws.Cells(i, "C"), ws.Cells(i, "E")).Address & ":Rangeオブジェクト"
            With ws
                Debug.Print .Range(.Cells(i, "C"), .Cells(i, "E")).Address & ":Rangeオブジェクト With省略"
            End With
            Debug.Print ws.Range("C" & i, "E" & i).Address & ":文字列2"
            Debug.Print ws.Range("C1:E1").Rows(i).Address & ":Range&Rows"
            Debug.Print ws.Rows(i).Columns("C:E").Address & ":Range&Columns"
        Next i
    End Sub

 あと、色々やってて、これだとオブジェクトエラーじゃないんだなと、新たに発見。なぜかは不明。
    Sub a()
        On Error Resume Next
        Debug.Print Range([Sheet1!a1], [Sheet2!a1]).Worksheet.Name
        Debug.Print Err.Description
        On Error GoTo 0
    End Sub
「指定した名前のアイテムが見つかりませんでした。」

(稲葉) 2020/08/31(月) 18:13


半平太さん、γさん、まっつわんさん
ルールでそうなっていたのですね。いろいろ試してどれが通るか、通らないか確認できたのでをやっとすこし理解できた気がします。ありがとうございます。
稲葉さん
アクティブシートに関してはほかのシートに変わった時に危険という事はわかりましたので、いまはそのぐらいの理解でいようと思います。いろいろ詰め込むとパンクしてしまうので、参考のコードありがとうございます。
(k) 2020/09/01(火) 13:53

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.