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

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

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

エクセルの日付を取得したときのデータ型の変換について

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

■87958 / inTopicNo.1)  エクセルの日付を取得したときのデータ型の変換について
  
□投稿者/ 河童 (5回)-(2018/07/20(Fri) 14:39:45)

分類:[C#] 

いつも大変お世話になっております。

エクセルファイルのセルに入力された日付を
C#で取得すると数値になってします。
C#で日付に変換する方法を教えて下さい。

環境
VS2010
Excel2010

やりたいこと
エクセルのセルから日付を取得して、
その値を文字列の編集に代入したいです。。

現状の処理
・日付が入力されているセルが空白かどうかチェック
・空白でなければ数値に変換
・数値に変換した値を日付に変換

困っていること
・セルが数値で入力されていたら困る
エクセル側で日付形式にしているのでないとは思うが
 一応C#側でもチェックをかけたい。
・もう少しスマートな変換方法を知りたい。

string nextmonth_inp;
// 翌月日のセルの値をセット
string cell_nextmonth = worksheet.Cell(Row, NexrtMonth_Column).Value.ToString();

if (cell_nextmonth != "")
{
double d = double.Parse(cell_nextmonth);
DateTime val = DateTime.FromOADate(d);

// DateTimeに変換できるか確かめる
DateTime nxtdt;
if (val != null)
{
nextmonth_inp = val.ToString("yyyy/MM/dd HH:mm"); ;
}
}
引用返信 編集キー/
■87960 / inTopicNo.2)  Re[1]: エクセルの日付を取得したときのデータ型の変換について
□投稿者/ 魔界の仮面弁士 (1743回)-(2018/07/20(Fri) 19:03:23)
No87958 (河童 さん) に返信
> string cell_nextmonth = worksheet.Cell(Row, NexrtMonth_Column).Value.ToString();

worksheet.Cells ではなく
worksheet.Cell という記述になっているということは
Excel オートメーションや EPPlus による操作ではなく、
ClosedXML にて操作している、という事でしょうか。


もしもそうなら、
 var cell = worksheet.Cell(Row, NexrtMonth_Column);
 if (cell.TryGetValue<DateTime>(out nxtdt))
 {
 }
などとしてみるとか。

Excel は、1900/02/29 の存在を認めているので、
1900/03/01 以前の日付を取得する場合はズレが生じることに注意。


もしも文字列としての日付と、日付値としての日付を区別したいなら、
 XLDataType t = cell.DataType;
が、Text/Number/Boolean/DateTime/TimeSpan のいずれなのかを調べたり、
cell.Style.NumberFormat を得るなりするとか。


> ・セルが数値で入力されていたら困る
DataType で判定できませんかね。
引用返信 編集キー/
■87964 / inTopicNo.3)  Re[2]: エクセルの日付を取得したときのデータ型の変換について
□投稿者/ 河童 (9回)-(2018/07/21(Sat) 10:15:27)
おはようございます。
魔界の仮面弁士さん、お返事ありがとうございます。

はい、そうです。
ClosedXMLを使っています。

if (cell.TryGetValue<DateTime>(out nxtdt))
を試してみたのですが、
日付として認識していないみたいです。

値としては、
43330.0
が入っています。

エクセル側で日付のみ入力するようにして
数値の判定はしなくていいようにします。


引用返信 編集キー/
■87965 / inTopicNo.4)  Re[3]: エクセルの日付を取得したときのデータ型の変換について
□投稿者/ 魔界の仮面弁士 (1744回)-(2018/07/21(Sat) 11:32:27)
No87964 (河童 さん) に返信
> 値としては、
> 43330.0
> が入っています。
Excel の数式バーにも、そう表示されている状態なのでしょうか。


> エクセル側で日付のみ入力するようにして
> 数値の判定はしなくていいようにします。
「43330.0」なのであれば、DataType プロパティの返却値は
XLDataType.Number または XLDataType.Text であろうかと思います。

まずは TryGetValue<DateTime> で取得し、それが false を返すようなら
続けて TryGetValue<Double> で受けるようにすれば、日付でも数値でも受け取れるので、
数値なら FromOADate で日付化する流れにしてみてはどうでしょう。


ただし、日付値を使う場合の注意点として:

(1) Excel で日付値としてとりうる数値リテラルの範囲は、
 Double 精度で「0.0以上 1.0未満」および「1.0 以上 2958465.9999942197 以下」となります。
 負数や 2958465.99999422 以上は日付値として扱うことができません。

(2) OADate 値は「-657434.99999999988 以上 2958465.9999999939 以下」をサポートします。
 -657434.0 以下や 2958465.9999999944 以上は NG です。
 OADate の最大値は、Excel の最大値より 5.7742E-06 だけ大きい値です。

(3) OADate の「61.0 以上」が指す範囲の日付値は、Excel 側の日付値と一致します。
 なお、61.0 は『1900/03/01 00:00:00』を指します。

(4) OADate の「1.0 以上 60.0 未満」が指す範囲の日付値は、Excel 日付の前日を指します。
 Excel 側では 2.0 を『1900/01/02 00:00:00』として扱います。
 OADate側では 2.0 を『1900/01/01 00:00:00』として扱います。
 Excel 側では 1.0 を『1900/01/01 00:00:00』として扱います。
 OADate側では 1.0 を『1899/12/31 00:00:00』として扱います。

(5)「60.0以上 61.0未満」の範囲は、OADate 側では
 『1900/02/28 00:00:00〜1900/02/28 23:59:59』を指しますが、
 Excel 側においては、本来は存在しないはずの うるう日 である
 『1900/02/29 00:00:00〜1900/02/29 23:59:59』を指します。

(6)「0.0以上 1.0未満」の範囲は、OADate 側では
 『1899/12/30 00:00:00〜1899/12/30 23:59:59』を指しますが、
 Excel 側においては、特殊な日付値として
 『1900/01/00 00:00:00〜1900/01/00 23:59:59』を意味します。

引用返信 編集キー/
■87976 / inTopicNo.5)  Re[4]: エクセルの日付を取得したときのデータ型の変換について
□投稿者/ 河童 (12回)-(2018/07/21(Sat) 14:39:06)
こんにちは。
魔界の仮面弁士さん、お返事ありがとうございます。

日付値の注意点、奥が深いです。

エクセルの数式バーには
2018/8/18
が表示されています。

コードは、下記のようにしてみました。

1.文字列型の変数にセルの値を代入
2.空白かどうかチェック
3.空白以外ならdouble型に変換
4.変換した値をFromOADataで日付に変換

自分的にはあまりしっくりこないですが、
とりあえず日付になっています。

//日付の取り込み
string cell_nextmonth = worksheet.Cell(Row, NexrtMonth_Column).Value.ToString();

if (cell_nextmonth != "")
{
   double d = double.Parse(cell_nextmonth);
   DateTime val = DateTime.FromOADate(d);

   //DateTimeに変換できるか確かめる
   if (val != null)
   {
      add_data = val.ToString("yyyy/MM/dd HH:mm"); ;
   }
}


引用返信 編集キー/
■88017 / inTopicNo.6)  Re[5]: エクセルの日付を取得したときのデータ型の変換について
□投稿者/ 河童 (16回)-(2018/07/30(Mon) 11:21:29)
日付のセルを取得した時に、数値になっていた原因がわかりました。

セルの書式設定でユーザー定義を使って書式を設定していました。
普通の日付型にすると、そのまま日付を取得できました。

お騒がせして申し訳ありませんでした。
解決済み
引用返信 編集キー/

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


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

このトピックに書きこむ