C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

【ExcelVBA】ifで日付を判定

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■96835 / inTopicNo.1)  【ExcelVBA】ifで日付を判定
  
□投稿者/ 工場プログラマー (57回)-(2021/02/17(Wed) 16:59:46)

分類:[.NET 全般] 

Windows10

For〜Nextで日付計算(DateDiff)しているんですが、
例えばA1セルに2020年2月17日が入っている → TRUE
   B1セルに2020年のみが入っている   → ERROR
になります。
Date型じゃないのでERRORになるのは当たり前ですがifで回避させようと考えています。
ifでA1セルのみ判定するにはどんなコードがありますか?


引用返信 編集キー/
■96836 / inTopicNo.2)  Re[1]: 【ExcelVBA】ifで日付を判定
□投稿者/ 魔界の仮面弁士 (2970回)-(2021/02/17(Wed) 18:27:47)
No96835 (工場プログラマー さん) に返信
> For〜Nextで日付計算(DateDiff)しているんですが、

DATEDIF (ワークシート関数) ではなく、
DateDiff (VBA 関数) の方の話でしょうか。


たとえば 2000/12/31 から 2002/01/01 までの差は「1年と1日」ですよね。
この場合、「年数」を求めようとすると
DATEDIF は「1」年と算出されて、
DateDiffは「2」年と算出されます。どちらがお好みですか?



> Date型じゃないのでERRORになるのは当たり前ですが
「2020年」と記録されている B1 セルの値は何ですか?
数値なのか文字列なのかそれとも…?


> ifで回避させようと考えています。
入力内容に応じてプログラムの動きを変化させるのではなく、
入力値を常に日付値あるいは整数値の何れかに統一した方が良いと思いますよ。

たとえば B1 セルの書式を「yyyy」あるいは「yyyy"年"」にして、そこに日付を入れておくようにすれば、
セルの見た目は「2020」や「2020年」にしつつ、Date 値同士の演算を行うことができます。

あるいは、
 Debug.Print Year([A1].Value)
などとして、「2020年2月17日」なセル値を「2020」という Integer 値に変換することもできます。
この場合、Date 型同士の日付演算ではなく、整数演算で求められますね。


> ifでA1セルのみ判定するにはどんなコードがありますか?
VBA 側だと
 [A1].Text → セル書式に応じた String 値
 [A1].Value → セル書式に応じて Date だったり Double だったり String だったり Empty だったり
 [A1].Value2 → Value に近いが、日付セルであっても Double で返す
 [A1].NumbeFormat → セルの書式を返す
というプロパティがあります。
戻り値の型を判定したい場合は、VarType 関数または TypeName 関数を併用できます。


ワークシート関数側なら、
 =CELL("format",A1) → セルの書式を返す
 =ISBLANK(A1) → 空白ならTRUE
 =ISNONTEXT(A1) → 文字列以外ならTRUE
 =ISTEXT(A1) → 文字列ならTRUE
 =ISNUMBER(A1) → 数値ならTRUE
などが使えます。
引用返信 編集キー/
■96841 / inTopicNo.3)  Re[2]: 【ExcelVBA】ifで日付を判定
□投稿者/ 工場プログラマー (58回)-(2021/02/18(Thu) 10:30:11)
No96836 (魔界の仮面弁士 さん) に返信
> ■No96835 (工場プログラマー さん) に返信
>>For〜Nextで日付計算(DateDiff)しているんですが、
>
> DATEDIF (ワークシート関数) ではなく、
> DateDiff (VBA 関数) の方の話でしょうか。

VBAです。

> たとえば 2000/12/31 から 2002/01/01 までの差は「1年と1日」ですよね。
> この場合、「年数」を求めようとすると
> DATEDIF は「1」年と算出されて、
> DateDiffは「2」年と算出されます。どちらがお好みですか?

切り捨てたいのでDATEDIFですね。

>>Date型じゃないのでERRORになるのは当たり前ですが
> 「2020年」と記録されている B1 セルの値は何ですか?
> 数値なのか文字列なのかそれとも…?

2020年だけなので判定は文字列です。
セルの書式は日付型です。
言い忘れてましたがA1もB1も変数Date型に格納して使用しています。
(例)DateDiff("yyyy", "hogehoge", Now)
これで型が一致しませんと言われます。

>>ifで回避させようと考えています。
> 入力内容に応じてプログラムの動きを変化させるのではなく、
> 入力値を常に日付値あるいは整数値の何れかに統一した方が良いと思いますよ。
>
> たとえば B1 セルの書式を「yyyy」あるいは「yyyy"年"」にして、そこに日付を入れておくようにすれば、
> セルの見た目は「2020」や「2020年」にしつつ、Date 値同士の演算を行うことができます。
>
> あるいは、
>  Debug.Print Year([A1].Value)
> などとして、「2020年2月17日」なセル値を「2020」という Integer 値に変換することもできます。
> この場合、Date 型同士の日付演算ではなく、整数演算で求められますね。

確かにそれもいいですね。検討してみます。

>>ifでA1セルのみ判定するにはどんなコードがありますか?
> VBA 側だと
>  [A1].Text → セル書式に応じた String 値
>  [A1].Value → セル書式に応じて Date だったり Double だったり String だったり Empty だったり
>  [A1].Value2 → Value に近いが、日付セルであっても Double で返す
>  [A1].NumbeFormat → セルの書式を返す
> というプロパティがあります。
> 戻り値の型を判定したい場合は、VarType 関数または TypeName 関数を併用できます。

ありがとうございます。
テストしてみます。

> ワークシート関数側なら、
>  =CELL("format",A1) → セルの書式を返す
>  =ISBLANK(A1) → 空白ならTRUE
>  =ISNONTEXT(A1) → 文字列以外ならTRUE
>  =ISTEXT(A1) → 文字列ならTRUE
>  =ISNUMBER(A1) → 数値ならTRUE
> などが使えます。
引用返信 編集キー/
■96843 / inTopicNo.4)  Re[3]: 【ExcelVBA】ifで日付を判定
□投稿者/ 魔界の仮面弁士 (2972回)-(2021/02/18(Thu) 10:58:04)
No96841 (工場プログラマー さん) に返信
>>> B1セルに2020年のみが入っている   → ERROR
>>>
>> たとえば 2000/12/31 から 2002/01/01 までの差は「1年と1日」ですよね。
>> この場合、「年数」を求めようとすると
>> DATEDIF は「1」年と算出されて、
>> DateDiffは「2」年と算出されます。どちらがお好みですか?
>>
> 切り捨てたいのでDATEDIFですね。


2000/12/31 から 2002/01/01 までを『2年』と計算して良いのなら、
Year 関数を使って月や日を切り捨てて、西暦年だけにしてから算出します。
この場合、DataDiff や DATEDIF は不要で、単純な整数同士の引き算ですね。

2000/12/31 から 2002/01/01 までを『1年』と算出したいのであれば、
月日の部分も必須情報なので、「2020年のみが入っている」セルを処理することはできません。
この場合には、月や日の情報を補うようなルール付けが必要になりますね。
 案1) 年数のみで月日が無いセルは、月日が現在日付と同じものとして扱う
 案2) 年数のみで月日が無いセルは、月日が1月1日である物として扱う
 案3) 年数のみで月日が無いセルは、月日が3月31日である物として扱う
 案4) 年数のみで月日が無いセルは、月日が4月1日である物として扱う
 案5) 年数のみで月日が無いセルは、月日が12月31日である物として扱う
 案6) 年数のみで月日が無いセルは、入力値エラーとして扱う



> 2020年だけなので判定は文字列です。
> セルの書式は日付型です。

ということは、こんな状態のセルになっているということでしょうか。

Sheet1.[B1].NumberFormat = "yyyy""年""m""月""d""日"";@"
Sheet1.[B1].Value = "2020年"

もしも、"令和2年"、"H29"、"西暦2021年"、"1995年" や
"12月24日"、"2021年2月末日"、"'2000.01.23" などといった
文字列入力も認めるのであれば、利用可能文字列の定義と、
その場合の演算ルールまで細かく定義する必要があるでしょう。


一方、日付値用のセルに対して文字列入力することを
認めたくない場合は、『日付値の入力』を強制するために、
[データ]リボンの[データ ツール]-[データの入力規則]を
割り当てておくことをお奨めします。
引用返信 編集キー/
■96847 / inTopicNo.5)  Re[4]: 【ExcelVBA】ifで日付を判定
□投稿者/ 工場プログラマー (59回)-(2021/02/18(Thu) 12:59:48)
No96843 (魔界の仮面弁士 さん) に返信
> ■No96841 (工場プログラマー さん) に返信
> >>> B1セルに2020年のみが入っている   → ERROR
> >>>
> >> たとえば 2000/12/31 から 2002/01/01 までの差は「1年と1日」ですよね。
> >> この場合、「年数」を求めようとすると
> >> DATEDIF は「1」年と算出されて、
> >> DateDiffは「2」年と算出されます。どちらがお好みですか?
> >>
>>切り捨てたいのでDATEDIFですね。
>
>
> 2000/12/31 から 2002/01/01 までを『2年』と計算して良いのなら、
> Year 関数を使って月や日を切り捨てて、西暦年だけにしてから算出します。
> この場合、DataDiff や DATEDIF は不要で、単純な整数同士の引き算ですね。
>
> 2000/12/31 から 2002/01/01 までを『1年』と算出したいのであれば、
> 月日の部分も必須情報なので、「2020年のみが入っている」セルを処理することはできません。
> この場合には、月や日の情報を補うようなルール付けが必要になりますね。
>  案1) 年数のみで月日が無いセルは、月日が現在日付と同じものとして扱う
>  案2) 年数のみで月日が無いセルは、月日が1月1日である物として扱う
>  案3) 年数のみで月日が無いセルは、月日が3月31日である物として扱う
>  案4) 年数のみで月日が無いセルは、月日が4月1日である物として扱う
>  案5) 年数のみで月日が無いセルは、月日が12月31日である物として扱う
>  案6) 年数のみで月日が無いセルは、入力値エラーとして扱う

案2でやってみました。
いろいろ考えてくださってありがとうございます。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ