アプリ版:「スタンプのみでお礼する」機能のリリースについて

独学で色々調べながらVBA作成しています。うまくいかないので有識者の方からアドバイス頂ければ幸いです。

ブック:AAA.xlsx
シート(左から順に):原本、祝日リスト、1、2~31 ←1ケ月分のシートです。
シート:祝日リスト内には、セルB1~B20までyyyy/mm/ddの形で、祝日の
日付けが入っています。

下記やりたいことです。
祝日リスト内の、B1~B20までの値を格納する★
シート:1~31までの、セル:E1の値と★を照合する。
シートを回すロジックは理解しています。
シート:祝日リストのB1~B20をfor~next文で回し、シート:1のセルE1と値を照合させようとしましたが上手くいきませんでした。
先に、祝日リスト内の値を格納して、後で照合するのが良いのかと思いました。

よろしくお願い致します。

質問者からの補足コメント

  • ご指摘ありがとうございます。
    下記回答致します

    1.ご指摘通り、AAA.xlsmですね。
    2.日付けで間違いありません。
    3.本処理の前に、yyyy/mmを元にシートを作るロジックがあるので、31まで無い月はシートが作成されません。
    4.一致したらアクティブシートを削除するのですが、そこのロジックは完成しています。

    No.1の回答に寄せられた補足コメントです。 補足日時:2023/12/12 12:33
  • 再度ご指摘ありがとうございます。
    言葉足らずで申し訳ございません。
    仰る通りです。
    マクロ実行時にyyyy/mmの入力をします。
    その値を元に、必要なシート(30までなのか、31までなのか)を作成します。
    各シートのセル:E1には、yyyy/mm/ddの値が入るため、その値をもとにweekday関数で土日にヒットしたらそのシートを削除するまでは完成しています。
    ただ、別シートに事前に記入した祝日の日付けと、セル:E1の値がうまく合致せず行き詰まって質問させて頂きました。
    よろしくお願いいたします。

    No.3の回答に寄せられた補足コメントです。 補足日時:2023/12/12 18:10
  • 早々に回答頂きありがとうございます。返信遅くなり申し訳ございません。
    セル:E1の日付けと、祝日リストの日付を照合してカウントするのではありません。
    言葉足らずで申し訳ございません。

    各シート(1~31)のセル:E1には、yyyy/mm/ddで日付けが入っています。
    Weekday関数を使い、土日にヒットしたらそのシートを削除する。は完成しました。
    ですが、祝日リストの日付けと、E1の値照合がうまくいきません。
    ちゃんと祝日リストの日付けを見れてないような感じです。
    そこで本質問をさせて頂きました。
    よろしくお願い致します。

    No.2の回答に寄せられた補足コメントです。 補足日時:2023/12/12 18:17

A 回答 (5件)

No2です。



>祝日リストの日付を照合してカウントするのではありません。
リスト内にE1セルの日付と同じものが存在するかどうかを調べたいのではないのでしょうか?

No2の繰り返しになりますが・・
リスト内のそれぞれの値とE1の値を順に比べていってもよいですが、有無を調べれば良いだけと解釈してよいのなら、「リスト内のE1の値をカウントして」結果が0なら存在しない、1以上なら存在すると判断できるという意味です。
(関数が存在するので、それを利用すれば1行で済むし、同じことを判断できるという意味です。)


なお、ご質問には直接関係ありませんけれど、
雰囲気からすると、どうやら・・
 1)1日~31日までのシートを作成して
 2)土日祝日のシートを削除する
ということをなさろうとしているように感じられますが・・

1日~31日のシートを作成する際に、「土日祝日かを判断して、該当する日のシートは作成しない」ようにしておけば、わざわざ「後から削除して回る」ようなことをしなくても良さそうに思われますし、(大差はないにしても)そちらの方が効率の良い処理方法とも言えるでしょう。

・・という能書きだけでは「なんのこっちゃ?」かものような気がしますので、
以下は勝手に想定した処理内容にしてありますが、手順としては上記の方法で処理を行う例です。
ご参考までに。

※ 年月の指定方法が不明なので、以下ではコード内で指定しています。
※ 指定した年月の1か月のうち土日祝日ではない日のシートを作成し、
 シートの内容は、「原本」シートをコピーして、E1セルに日付をシリアル値
 で記入すると仮定しました。
※ 祝日のリストは「祝日リスト」シートのB1:B20と仮定。
※ AAA.xlsxは開いた状態であると仮定し、1~31のシートは存在しない状態で
 実行するものと仮定しています。
 (既に存在する場合には「同じ名前のシートがあります」のエラーになります)
 (最初に削除するか、存在チェックのコードを加えれば、エラーは防げます)

Sub Q13678867()
Dim ws As Worksheet
Dim holiday As Range
Dim d As Date

Const yy = 2023 ' ←指定の年
Const mm = 12 ' ←指定の月
With Workbooks("AAA.xlsx") ' ←指定のブック(開いているものとする)

Set holiday = .Worksheets("祝日リスト").Range("B1:B30")
For d = DateSerial(yy, mm, 1) To DateSerial(yy, mm + 1, 0)
If Weekday(d, 2) < 6 And Application.CountIf(holiday, d) < 1 Then

' ** 以下にシートの追加等の処理を記述する
' ** 適当に仮定した処理内容なので、実際のものに入れ替えてください
Set ws = .Worksheets.Add(After:=.Worksheets(.Worksheets.Count))
ws.Name = Day(d)
.Worksheets("原本").Cells.Copy ws.Cells
ws.Range("E1").Value = d
' ** ここまで

End If
Next d
End With
End Sub
    • good
    • 1
この回答へのお礼

ご連絡遅くなりました。
詳細にありがとうございました。
参考にさせて頂き、トライandテストしてみます。

お礼日時:2023/12/14 18:05

以下のマクロは、アクティブシートのE1の日付が祝日シートの日付に


あるかどうかを判定するマクロです。
下記のマクロをあなたが作成したマクロに取り込めば、良いかと思います。
不明点は補足してください。(ディクショナリを使っています)

Public Sub sample()
Dim ws As Worksheet
Dim dicT As Object
Dim wrow As Long
Dim key As Variant
Set ws = Worksheets("祝日リスト")
Set dicT = CreateObject("Scripting.Dictionary")
'祝日シートの祝日を記憶
For wrow = 1 To ws.Cells(Rows.Count, "B").End(xlUp).Row
key = ws.Cells(wrow, "B").Value
dicT(key) = True
Next
'アクティブシートのE1が祝日シートにあるか
key = Range("E1").Value
If dicT.exists(key) = True Then
MsgBox (key & "は祝日シートにあります")
Else
MsgBox (key & "は祝日シートにありません")
End If
End Sub
    • good
    • 1
この回答へのお礼

ご連絡遅くなり申し訳ございません。
詳細にありがとうございました。
参考にさせて頂き、テストandトライしてみます。

お礼日時:2023/12/14 18:07

No1です。

補足ありがとうございました。
補足の3番目ですが、
「3.本処理の前に、yyyy/mmを元にシートを作るロジックがあるので、31まで無い月はシートが作成されません。」
ということですが、
マクロでは、29,30,31のシートがあるかどうかが、事前にはわからないことになります。
従って、方法としては、
1案:マクロ実行時に、年月(yyyy/mm)の情報をどこかのセルに書いておき、それを参照して、その月の末日を求め、末日まで繰り返すようにする。

2案:無条件に1~31まで繰り返し、該当シートがない場合は、そのシートの処理はしないようにする。

の何れかになります。
私は、1案を推奨しますが、いかがでしょうか。

繰り返しの方法としては、
1.1~末日の繰り返し
2.その内側でB1:B20の繰り返し
が妥当かと思います。
この回答への補足あり
    • good
    • 0

こんにちは



>シート:1~31までの、セル:E1の値と★を照合する。
「照合」とは「一致するものがあるかどうか」がわかれば良いということと解釈しました。

ご質問文のように、値をそれぞれ比較してゆく方法でも可能ですけれど、有無さえわかればよさそうなので、
 Set L= WorkSheets("祝日リスト").Range("B1:B20")
とでもしておいて、実際の判断は各シートに対して
 n = Application.CountIf(L, WorkSheets("シート名").Range("E1"))
のようにすれば、一致する値の個数がnに得られますので、それで判断可能でしょう。
(n = 0 なら、一致するものはない)

>シートを回すロジックは理解しています。
とのことなので、上記をループできるようにすれば良いだけかと。
この回答への補足あり
    • good
    • 2

以下、補足要求です。


1.マクロは、ブック:AAA.xlsxではなく、他のブックに格納したいということでしょうか。(マクロをブック:AAA.xlsxに格納すると、ブック名は、AAA.xlsmになります)

2.シート:1~31のE1もyyyy/mm/dd形式で、日付が格納されていると理解しましたが、間違いないでしょうか。

3.シート:1~31についてですが、例えば2月の場合、シート:30、31のE1のセルは空白と考えて良いのでしょうか。

4.シート:祝日リストのB1~B20をfor~next文で回し、シート:1のセルE1と値を照合して、一致した場合、なにをなさりたいのでしょうか。
この回答への補足あり
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A