Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10 Pro : Excel 2016)
VBA 値の代入について
投稿日時: 24/07/08 15:11:12
投稿者: しん88

いつもありがとうございます。
よろしくお願いいたします。
 
入力シートに出勤、代休、有休の入力されています。
カレンダーに出勤、代休、有休の取得状況をカンマで繋げてセルに表示をさせたいと
思っております。
よろしくお願いいたします。
 
シート名:入力シート
氏名   出勤    代休    有休
佐藤   2024/7/1  2024/7/4
山田   2024/7/1  2024/7/3
鈴木   2024/7/2  2024/7/4
田中   2024/7/2  2024/7/5
宮田               2024/7/2
佐々木              2024/7/5 



 
シート名:カレンダー
日付   出勤    代休    有休  
2024/7/1 佐藤,山田
2024/7/2 鈴木,田中       宮田
2024/7/3       山田
2024/7/4       佐藤,鈴木
2024/7/5       田中    佐々木


 

回答
投稿日時: 24/07/08 16:34:28
投稿者: simple

# 暑いですねえ。
   
回答する前にいくつか質問させていただきます。
   
(1)これは現実的な話を質問されていますか?
   それとも、実際は勤務管理じゃなく別のことですが、
   分かりやすい例として勤務管理になぞらえて質問しているんですか?
      
   というのは、各人は月に1回程度出勤するだけなんですか?
   いや説明を端折っているが、通常の月〜金出勤です、ということなら、
   入力シートも出力シートも変わってきませんか?
      
   ・有給、代休、特別休暇以外は通常勤務と見做して、入力は不要とするとか、
   ・出力も、
     ・勤務表は、縦に日付、横に氏名を入れて勤務者だけ〇を付したマトリックス表示にする
     ・欠勤表は、縦に日付、横に欠勤理由とし、該当者名をカンマ連結させて表示する(案通り)
     とかになりませんか?
  
   現状の方針は、なんだか使いにくい気がして、考える気力が湧きにくい。
   
(2)VBAのコード作成に関して、ご自分ではどんなトライをされて、どこで詰まっていますか?
   そのあたりを説明していただくと、こちらの掲示板の趣旨をより生かすことができます。

回答
投稿日時: 24/07/10 07:19:03
投稿者: simple

反応が無いのが残念です。
たぶん創作した設例でしょう。
 
Dictionary というデータ構造を使うコード例を書きます。
Sheet2の日付列は用意されている前提としています。
 

Sub test()
    Dim ws1 As Worksheet, ws2 As Worksheet
    Dim dic As Object           ' dictionary object  
    Dim lastRow1&, lastRow2&    ' & をつけるのは As Longと同じ
    Dim person$                 ' $ をつけるのは As Stringと同じ
    Dim d As Date
    Dim k&, j&

    Set ws1 = Worksheets("Sheet1")
    Set ws2 = Worksheets("Sheet2")
    Set dic = CreateObject("Scripting.Dictionary")

    lastRow1 = ws1.Cells(Rows.Count, "A").End(xlUp).Row
    lastRow2 = ws2.Cells(Rows.Count, "A").End(xlUp).Row

    For j = 2 To 4
        dic.RemoveAll               '列ごとにdictionaryを初期化して使用
        For k = 2 To lastRow1       'Sheet1のj列から、
                                    '日付別の情報をdictionaryに保持
            person = ws1.Cells(k, "A")
            d = ws1.Cells(k, j)
            If Not dic.Exists(d) Then
                dic(d) = person
            Else
                dic(d) = dic(d) & "," & person
            End If
        Next
        For k = 2 To lastRow2       'dictionaryの内容を Sheet2のj列に書込
            d = ws2.Cells(k, "A")
            ws2.Cells(k, j) = dic(d)
        Next
    Next
End Sub

回答
投稿日時: 24/07/10 18:36:28
投稿者: WinArrow

感想
 
「入力イート」も「カレンダーシート」も
一般的には理解が難しいです。
「カレンダーシート」:例示の形式は、何を目的に編集しているのでしょうか?
分析や検索もできないような表にンっていると思います。
どのような仕事に使うのですか?
 
 
 
 

回答
投稿日時: 24/07/11 08:01:59
投稿者: simple

別案を示します。

Sub test2()
    Dim ws1 As Worksheet, ws2 As Worksheet
    Dim lastRow1&, lastRow2&
    Dim rng    As Range
    Dim person As String
    Dim d      As Long          ' Longにするのがキモ
    Dim m
    Dim k&, j&
    
    Set ws1 = Worksheets("Sheet1")
    Set ws2 = Worksheets("Sheet2")

    lastRow1 = ws1.Cells(Rows.Count, 1).End(xlUp).Row
    lastRow2 = ws2.Cells(Rows.Count, 1).End(xlUp).Row

    Set rng = ws2.Range("A1", ws2.Cells(lastRow2, "A"))

    For j = 2 To 4
        For k = 2 To lastRow1
            person = ws1.Cells(k, "A")
            d = ws1.Cells(k, j).Value    'Value2とすると更に明確になるかも
            m = Application.Match(d, rng, 0)
            If Not IsError(m) Then
                If IsEmpty(ws2.Cells(m, j)) Then
                    ws2.Cells(m, j) = person
                Else
                    ws2.Cells(m, j) = ws2.Cells(m, j) & "," & person
                End If
            End If
        Next
    Next
End Sub
(なお、test,test2とも書き込み先の初期化を端折っていますが、そちらで補充してください。)
 
【参考】
日付の検索は、振る舞いがわかりにくいテーマのひとつだと思います。
もしFindを使う場合は、
http://officetanaka.net/excel/vba/tips/tips131.htm
から始まるいくつかのページを参照してください。
田中氏をして
> 日付の検索を一言で表すと「いろいろあって難しい」ってことですね。
> そのことだけ、忘れないようにしましょう。

と言わしめたテーマのようです。
 
# 出勤は休日出勤の意味でしたか。月曜、火曜が休みなんですか?
# 追加説明とか、なんらかのコミュニケーションをする意図はないのですか。

投稿日時: 24/07/12 17:07:13
投稿者: しん88

simpleさま WinArrowさま
身内に不幸がありまして帰省をしておりましたため、書き込みが大変遅くなり申し訳ありません。
ご質問もいただいておりましたのに、大変申し訳ありません。
 
実際は勤務管理ではないです。
たくさんコードを書き込んでくださりありがとうございます。
作業ができるのは来週になりそうですが、コードを読み込んで勉強したいと思います。
 
返信ができなかったこと、心よりお詫び申し上げます。