戻る  □一般操作のサロン  □ 使用方法  □ 新着記事  □ 新規に質問する!  □ トピック一覧  □ 検索  □ 過去ログ
[ 最新記事及び返信フォームをトピックトップへ ]
このトピック参照回数 :
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 としないと首尾一貫しないと思いますが、
               ~~~↑~
                        これは誰もやってない。不・思・議
      
      まぁ、初心者さんには小難しい話なので、上達したら読み返してください。
      


      この記事にはVBAのコードが含まれています。

      緑の太文字→注釈
      茶色の太文字→条件分岐
      赤の太文字→ループ
      青の太文字→その他




    [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プロパティは異次元な感じに見えますが、
      学習を続けていきたいと思います。




このトピック内容の全ページ数 / [0]

このトピックに書きこむ
Name/
E-Mail/

└>このツリーのレス記事をメールで受信しますか? YES/ NO/
Title/
URL/
Comment/ 通常モード->  図表モード-> (←の場合適当に改行を入れて下さい)
タグが使用できます。例 ⇒ <font color="blue">文字</font>
解決!!ありがとうございました! 解決       保留中です・・・ 保留        迷宮入りorほかあたって見ます・・ 迷宮入       すいませ〜ん。誰か〜! Help! ←※回答者専用
解決したらチェック       保留(コードテスト中など・・)         解決不可orレスが全く付かなくてほかのサイトに行くときなど・・
削除キー/
(半角8文字以内) 


- Child Forum -
Edit:ゆう-G