CLng +1,2と+1,3の書き方 | |
---|---|
[194626] CLng +1,2と+1,3の書き方- ■親トピック/記事引用/メール受信=OFF■ □投稿者/ junjun -(2022/01/17(12:12)) □U R L/ 皆さま、お忙しい中申し訳ございません。 以前、このサイトでご回答を頂いたのですが、 コードを応用するために、機能を調べております。 どうしてもわからない箇所があり、 何を意味するかご教示頂けますでしょうか。 ●以前の質問 タイムカードの集計をしているのですが、 お店の営業日と勤務日が一致していないデータがあります。 同じ日付を同列にするのはどのようにしたらよいでしょうか。 例) A | B | C 1 営業日 | 出勤時刻 | 退勤時刻 2 2021/10/1 | 2021/10/2 10:30 | 2021/10/2 22:00 3 2021/10/2 | 2021/10/3 10:30 | 2021/10/2 21:00 4 2021/10/5 | 2021/10/6 11:00 | 2021/10/2 22:00 下記のようにしたいと思っております。 A | B | C 1 営業日 | 出勤時刻 | 退勤時刻 2 2021/10/1 | | 3 2021/10/2 | 2021/10/2 10:30 | 2021/10/2 22:00 4 2021/10/3 | 2021/10/3 10:30 | 2021/10/2 21:00 5 2021/10/4 | | 6 2021/10/5 | | 7 2021/10/6 | 2021/10/6 11:00 | 2021/10/2 22:00 色々なネットの記事、本などを読んだのですが分からないでいます。 ご教示いただけますと幸いです。 なにとぞ、宜しくお願い申し上げます。 ●頂いたご回答 □投稿者/ 半平太 -(2021/12/24(12:33)) □U R L/ Sub TEST() Dim r As Range, cel As Range Dim StDay As Date, EdDay As Date Dim Result Dim dys As Long StDay = Application.EoMonth(Application.Max(Columns("A")), -1) + 1 dys = Day(Application.EoMonth(StDay, 0)) EdDay = StDay + dys - 1 With Range("E2") '取り敢えず、打ち出し先をE2として、日付だけ埋めてみる .Value = StDay .AutoFill Destination:=Range("E2").Resize(dys), Type:=xlFillDays Result = .Resize(dys, 3).Value '日付の配列を格納 End With Set r = Range("B2", Cells(Rows.Count, "B").End(xlUp)) For Each cel In r If cel <> "" Then '念の為 Result(CLng(cel) - StDay + 1, 2) = cel Result(CLng(cel) - StDay + 1, 3) = cel.Offset(, 1) End If Next Range("E2").Resize(dys, 3) = Result End Sub ●今回の質問 *抜粋 For Each cel In r > If cel <> "" Then '念の為 > Result(CLng(cel) - StDay + 1, 2) = cel > Result(CLng(cel) - StDay + 1, 3) = cel.Offset(, 1) > End If > Next * *抜粋ここまで 上記3行目、4行目の+1,2と+1,3が何を意味するか分からないでいます。 Offset(,1)はF列→G列へ参照範囲を移動しているのが分かったのですが、 3行目、4行目が分らず・・・です。 (CLngは丸めと認識しております) ご教示いただければ幸いでございます。 なにとぞ、宜しくお願い申し上げます。 この記事にはVBAのコードが含まれています。 緑の太文字→注釈 茶色の太文字→条件分岐 赤の太文字→ループ 青の太文字→その他 ++++++++++++++++++++ OS ⇒OTHER Version⇒OTHER ++++++++++++++++++++ |
[194628] Re[1]: CLng +1,2と+1,3の書き方- ■記事引用/メール受信=OFF■ □投稿者/ 半平太 -(2022/01/17(15:38)) □U R L/ あれ? EdDayは使ってないですね。(消してください) > Result = .Resize(dys, 3).Value '日付の配列を格納 上のステートメントによって、Resultに「E2:G32の値の配列」が格納されます。 つまり、Result(1 to 31, 1 to 3) と言う配列になっています。 Resultの列は(1 to 3)の3列あります。 1は日付用だとして、残りの2と3は何かと言えば、 これから埋める出勤時刻と退勤時刻用の入れ物です。 さて、Resultに出勤時刻と退勤時刻を埋めて行く訳ですが、 例えば、10/5 のデータは、Resultの上から何番目に書き込んだらいいでしょうか? 5日だから、5番目ですよね。なので Result(Day(cel), 2) = cel Result(Day(cel), 3) = cel.Offset(, 1) とやればいいです。 それならjunjunさんが戸惑うこともなかったでしょう。 でもやらなかった。 何故か? 単に私があほだからです。 ついでに、これでも旨くいった理由だけ説明します。 ↓ > Result(CLng(cel) - StDay + 1, 2) = cel ~~~~~↑~~~ ~~↑~~~ ~ 10/5 - 10/1 + 1 ~~~~~~~~~~~~~~~~~~~~~ つまり、これでも5となります。 尚、両者で少し違いが出ることがあります。 万一、出勤日が10月じゃないデータが紛れ込んでいた場合、 例えば、11/5の場合、 Result(Day(cel), 2) = cel はエラーにならず、5番目に書き込まれます。 しかし、エラーにならない事が全ていい訳でもないです。 10月しか処理していないハズなので、エラーになった方がマシとも言えます。 |
[194640] Re[2]: CLng +1,2と+1,3の書き方- ■記事引用/メール受信=OFF■ □投稿者/ junjun -(2022/01/18(10:01)) □U R L/ 半平太様 いつもご教示誠にありがとうございます。 お忙しい中対応下さり、感謝でございます。 EdDayの件、承知致しました。 不勉強で申し訳ございません、 下記のコードはこのような意味がありますでしょうか。 ●5日目の場合 Result(Day(cel), 2) = cel →Result(5, 2) = cel Result(Day(cel), 3) = cel.Offset(, 1) →Result(5, 3) = cel.Offset(, 1) もし仮にそうだとした場合、cells(5,2)やcells(5,3)とはせず、 表示出来るのですかね? cellsの省略、あるいは表記ルールがあるのでしょうか。 また、Result(5, 3)でG列をカバーしている気がしますが、 Offset(, 1)もどのような意味を持つのかご教示頂ければと思います。 Result(5, 2)のOffset(, 1)、つまり1列右を参照という意味合いでしょうか。 ご教示頂ければ幸いでございます。 なにとぞ、宜しくお願い申し上げます。 |
[194641] Re[3]: CLng +1,2と+1,3の書き方- ■記事引用/メール受信=OFF■ □投稿者/ 半平太 -(2022/01/18(13:41)) □U R L/ >下記のコードはこのような意味がありますでしょうか。 >●5日目の場合 >Result(Day(cel), 2) = cel >→Result(5, 2) = cel 全く同じ意味です。 >もし仮にそうだとした場合、cells(5,2)やcells(5,3)とはせず、 >表示出来るのですかね? >cellsの省略、あるいは表記ルールがあるのでしょうか。 うーん、Resultは単なる値配列です。 ResultをRangeオブジェクトと勘違いしていないですか? ResultをRangeオブジェクトにするなら > Result = .Resize(dys, 3).Value '日付の配列を格納 ↓ Set Result = .Resize(dys, 3) '$E$2:$G$32範囲をオブジェクト変数に格納 と書く必要があります。また、 Range("E2").Resize(dys, 3) = Result は不要化します。ループ内でセルに直接書き込むので。 つまり、↓ となる。 Sub TEST2() Dim r As Range, cel As Range Dim StDay As Date Dim Result Dim dys As Long StDay = Application.EoMonth(Application.Max(Columns("A")), -1) + 1 dys = Day(Application.EoMonth(StDay, 0)) With Range("E2") '取り敢えず、打ち出し先をE2として、日付だけ埋めてみる .Value = StDay .AutoFill Destination:=Range("E2").Resize(dys), Type:=xlFillDays ' Result = .Resize(dys, 3).Value '日付の配列を格納 Set Result = .Resize(dys, 3) '$E$2:$G$32範囲をオブジェクト変数に格納 End With Set r = Range("B2", Cells(Rows.Count, "B").End(xlUp)) For Each cel In r If cel <> "" Then '念の為 Result(Day(cel), 2) = cel Result(Day(cel), 3) = cel.Offset(, 1) End If Next 'Range("E2").Resize(dys, 3) = Result '不要化 End Sub さて、質問にあった「Cells・・」がない状態には変わりありません。 Cellsを書きたければ Result.Cells(Day(cel), 2) = cel Result.Cells(Day(cel), 3) = cel.Offset(, 1) となります。 では、書いても書かなくてもいいのか? って事になります。 以下、少し難しい話になります。 Rangeオブジェクトにはタイプが3つあります。 Cells型、Rows型、Columns型 Cells型は、Cellsを書かなくてもいいんです。 慣れないと書かずにはいられないでしょうけどね。 逆に言うと、慣れの問題でしかなく、書かないのが正しいと言ってもいいです。(これが万人に受けいれられるか分からないですけどね) 何故なら、Cells型なのに、さらにCellsを付けてCells型に変換するのは屋上屋を架す愚行だからです。 (Rows型やColumns型をCells型に変換する時は必須となる) そうは言っても後ろにある(行、列)の引数の顔が立たないじゃないか、と思うかも知れませんが、 驚かないでくださいよ、それはCellsプロパティの引数じゃないんですよ。Cellsとは無関係の代物です。 じゃ、何の引数なのかと言うことになりますが、Itemプロパティのです。 ただ、ItemはRangeオブジェクトの規定のプロパティなので省略できます。 ※規定のプロパティはValueじゃなかったっけと言う話は、更に難しい話になりますので、ここでは深入りしません Itemプロパティの省略は余りにも一般化しているので、省略している意識さえない人がほとんどでしょう。 >また、Result(5, 3)でG列をカバーしている気がしますが、 >Offset(, 1)もどのような意味を持つのかご教示頂ければと思います。 >Result(5, 2)のOffset(, 1)、つまり1列右を参照という意味合いでしょうか。 1列右を参照ですが、その基になるセルはB列ですよ。つまり、cel.Offset(, 1)はC列です。 B列のセルを一つずつcelに取り出している所です。(celは変数です。Cellsプロパティとは無縁です) ↓ > For Each cel In r 「r」が何だったか思い出してください。 そう言えば、上のCellsの議論を踏まえれば、Cellsが書きたくてしょうがない人は、 For Each cel In r.Cells としないと首尾一貫しないと思いますが、 ~~~↑~ これは誰もやってない。不・思・議 まぁ、初心者さんには小難しい話なので、上達したら読み返してください。 |
[194643] Re[4]: CLng +1,2と+1,3の書き方- ■ / 記事引用/メール受信=OFF■ □投稿者/ junjun -(2022/01/19(17:46)) □U R L/ 半平太様 いつもご教示誠にありがとうございます! なるほどですね、値の配列なのか単に表示するのか 違いが分かっていませんでした。 また、rはB2の最後の行までを対象としていて、 それを元にそれぞれの空白では無いセルをResizeの中に格納、 2列目はB列、3列目はoffset(,1)でC列を指定しているのですね。 良く分かりました。 分かりやすいご回答、誠にありがとうございました。 Itemプロパティは異次元な感じに見えますが、 学習を続けていきたいと思います。 |
このトピックに書きこむ |
---|