塗りつぶされていないセルをカウントするには?

(休日カレンダーから実働日数を計算するには?)
Question 10.4 Previous Next
下図は「休日表」です…(注、画面表示の都合上一部分)…。できたら回答お願いします。
休日表
この表のある範囲(例えば1998/10/12~1999/3/01)で、休日(塗りつぶされたセル)をのぞく、実労働日数を計算させたいのです。
Answer   Copyright (C) 1998.9.17 永井善王
このテーマは、人間が目で見て数えると簡単にできますが、マクロに組むのは少々やっかいだと思います。
なぜかと言うと、1) セルが塗りつぶされているかどうかの判別方法、
          2) 月だけで年が入力されていない行があるので、その算出ロジック、
          3) 大の月、小の月に応じた処理、
          4) 「ある範囲」で指定された期間分を休日表から抜き出すロジック、
          5) 休日表に「指定された期間」のデータがない場合のフォロー、
          6) 実労働日数のトータルだけ計算すれば良いのか、月別も必要か?
          7) 期間は両端入れ、両端落し、片端入れなら前後どちらを入れるか、
などが挙げられ、これらをクリアしなければならないからです。

すべてをマクロで組むことも可能ですが、複雑なプログラムになりそうですし、「Do Loop」や「For Next」 に頼り過ぎると処理時間がかかる場合があります。
エクセルのブック機能と式や関数をうまく利用することを第一に考え、マクロは補完程度にとどめましょう。

以下にフレームを描いてみました。ブックを6枚のシートで構成します。
第1 休日表シート … 上図のシート、データは13カ月分以上入れても良い(下記制限事項を参照)
第2 年月シート …… 休日表の年と月の列(A列とB列)だけを写して、年月6桁に変換するためのシート
第3 抜出シート …… 「ある範囲」で指定された期間分だけを、休日表から抜き出して貼り付けるシート
              (レイアウトは休日表と同じ、ただし13カ月分だけ)
第4 合成シート …… 年月シートの年月と日を合成(8桁化)するためのシート(レイアウトは抜出シートと同じ)
第5 判別シート …… 合成シートの塗りつぶされたセルを判別し日数計算のフラグを立てるシート(レイアウトは同上)
第6 結果シート …… 判別シートのフラグを集計して、実働日数などを表示するためのシートです。

制限事項は下記のとおりとします。
1) 休日表の各項目の入力ルールは上図のとおり(例えば1998年のように年をつける)。
  1カ月分は必ず2行で構成される。
  最小年月が2行目にあり、順次、下方向に最大年月まで連続していること。
2) 「ある範囲」で指定できる期間は最長1年間(足掛け13カ月)

各シートの作り方
年月シート … 新しいワークシートを挿入してシート名を「年月」にします。何も入ってない状態で、 マクロで使います。
抜出シート … 同様にしてシート名を「抜出」にします。このシートも、まっさらで良い。 マクロ で使います。
合成シート … 同様にして「合成」に。まっさら。
マクロ で使う。
判別シート … 同様にして「判別」に。まっさら。
マクロ で使う。
結果シート … 同様にして「結果」に。レイアウトは
こちら を参照し、式を埋め込んで おきます。

最後になりましたが、「ある範囲」は インプットボックスで入力すると良いかと思います。マクロは
こちら
インプットボックスのマクロは、そんなに難しいものではありませんが、他人が使うのであれば、ありえない日付などの入力ミスへの対策が、必要になるでしょう。その場合は少々難しくなります。

まるでプラモデルを組み立てるように感じるかも知れませんが、エクセルのブックは何枚もシートを入れれます。少ないシートで複雑なマクロを組むよりも、処理の段階を適当に区切って組んだ方が楽ですし、後日とか、他人が見ても理解しやすいと思います。
エクセルらしく使いましょう。

以上のとおり回答しますので、根気良く組み上げてみてください。

Excel VBA Macro