ファイルから更新日時を取得し、テキストに更新日時を格納する為には

解決


Delphi大好き  2009-05-15 02:24:26  No: 34391

環境はWinXP SP3  TurboDelphi2006(無償版)です。

以前作った画像管理ソフトの全面改良をしています。

データベースで、ファイルからファイル更新時刻を取り出し、
データベースに格納させます。

以下が問題のコード(一行だけですいません)です。

FieldByName('撮影日時').AsString := Datetostr(FileDateToDateTime(fileage(strpas(filename))));

ドラックアンドドロップで取得したファイル名からFileageで更新日時を取得しています。

日付検索を簡単に出来る様にする為に、Filedの型をStringに変えました。
以前はDatetime型でした。

filenameの型は、FileName: array [0..255] of Char;
です。

以前(Datetime型の時)は正常に作動していました。

が、ソフト変更後、
「日付に変換出来ない値が渡されました」
とエラーが出て、日付を取得出来なくなりました。

試しに更新前のソフトで試した所、これも正常に動かず、
同じエラーメッセージが出るようになりました。

古いソフトのコードです
FieldByName('撮影日時').AsDateTime := FileDateToDateTime(fileage(strpas(filename)));

現在はどちらのソフトも正常に動いていません
色々試したのですが、何度やっても上記のエラーが出ます。

データベースに格納する前にエラーで止まってしまうようです。
 FileDateToDateTime(fileage(strpas(filename)));
だけでも上記と同じエラーになってしまいます。

どなたかお知恵を拝借いただけないでしょうか?

追記です。
ウイルス対策ソフトはウイルスセキュリティ0を使っています。
(以前、それが原因でエラーが出て困ったというスレッドがあったので)

Delphi自体も、プロジェクトを閉じると、
モジュール'oleaut32.dll'のアドレス  770D4945  でアドレス734F1E88に対する読み込み違反が起きました

とエラーが出ます。
ウイルスソフトをノートンからウイルス0に変えてからエラーが出るようになりました。

気にはなったので追記した次第です。

ウイルスソフトと干渉してしまっている為のエラーでしょうか?
それともやはりプログラムエラーなのでしょうか?

それではよろしくお願いします。


igy  2009-05-15 03:44:35  No: 34392

> FileDateToDateTime(fileage(strpas(filename)));
>だけでも上記と同じエラーになってしまいます。

エラーが出るときの、

filename
strpas(filename)
fileage(strpas(filename))

の内容は、どのようになっていますか?


Delphi大好き  2009-05-15 20:20:18  No: 34393

igyさん早速ありがとうございます、
値は以下になります。

>ドロップしたファイル名
C:\Documents and Settings\XXX\デスクトップ\試し\35.JPG
更新日時  2008年12月22日、15:53:28

>igyさんへの返答部分
filename                    :→Char型のまま値を取得する方法が判りませんでした・・・
strpas(filename)            :C:\Documents and Settings\XXX\デスクトップ\試し
fileage(strpas(filename))  :1899/12/29

になります。
ファイル名の取得が出来てないですね・・・
ミスっぽい・・・;

>エラーが出る部分のデータベースに登録された値
フォルダ名(Field名場所)  C:\Documents and Settings\XXX\デスクトップ
ファイル名  試し
更新日時    2009/05/06 12:12:00(何故か、一つ前の正常に登録されているファイルの更新日時が入ってる)

>別の登録方法で、同じファイルを正常に登録されたデータベースの値です。
フォルダ名(Field名場所)  C:\Documents and Settings\XXX\デスクトップ\試し
ファイル名  35.jpg
更新日時    2008/12/22 15:53:28

どうやら、自分のバグですね・・・
何故正常稼動していた旧ソフトまでが動かなくなったのは謎ですが・・・

>異常があるドラックドロップのコードです

変数一覧
var
    s:string='';//画像表示格納変数
    s1:string='';//デジカメカードのフォルダ名格納変数
    s2:string='';//画像の保存先の大元フォルダ名
    s3:string='';//画像ファイル名格納変数
    s4:string='';//画像フォルダ名格納変数
    s5:string='物件名';//一時格納変数フォルダ名用
    s6:string='フォルダ名';//復元サブフォルダ名格納変数
    s7:string='';//復元先フォルダ名格納変数ドラックドロップ時用
    s8:string='';//復元先フォルダ名格納変数自動格納部分用
    x1,y1,x2,y2:integer;//座標変数
    count1:integer=0;//画像ファイル最大数記録用
    count2:integer=0;//復元ファイル数記録用変数
    sw1:boolean=false;//ドライブ見つかった時用フラグ
    sw2:boolean=false;//座標取得フラグ
    sw3:boolean=false;//画像無いとき初期化フラグ
    sw4:boolean=false;//画像非表示フラグ

>エラーの出るドラックドロップ部分(書いてからバグで止まってしまっているので、動作未確認の部分でバグが沢山ある筈と思います)
procedure TForm1.WMDropFiles(var Msg: TWMDropFiles);
var
  FileName: array [0..255] of Char;
  I, Num: Word;
begin
  DragQueryFile(Msg.Drop, 0, FileName, SizeOf(FileName));
  s8 := strpas(FileName) + '\';
  form12.ShowModal;//ドロップしたファイル一覧のプリヴューウインドウ表示
  if InputQuery('写真の物件名を', '入力してください', s5) then
  else
    exit;

    Num := DragQueryFile(Msg.Drop, $FFFFFFFF, nil, 0);
    with datamodule7.table1 do begin
      last;
      edit;
      s4 := inttostr(FieldByName('ナンバー').AsInteger + 1);

      if not directoryexists(s2 + '\' + s4) then //指定したフォルダがないか検索
        createdir(s2 + '\' + s4) else begin end;   //無ければ作る

      for I := 0 to Num - 1 do begin
        DragQueryFile(Msg.Drop, I, FileName, SizeOf(FileName));

        FieldByName('フォルダ名').AsString := s2 + '\'+ s4;
        FieldByName('ファイル名').AsString := extractfilename(strpas(FileName));
        FieldByName('ナンバー').AsString := S4;
        FieldByName('撮影日時').AsString := datetimetostr(FileDateToDateTime(fileage(strpas(filename))));//問題の部分
        FieldByName('物件名').AsString := s5;
        FieldByName('場所').AsString := extractfiledir(strpas(filename));
        post;

        copyfile(filename,allocpchar(s2 + '\'+ s4 + '\' + extractfilename(filename)), false);

        Append;
      end;
    end;
   DragFinish(Msg.Drop);
  s5 := '物件名';
end;

>正常に動いている、自動認識で画像を取り込んでいる部分(Field部分を変更する以前に書き、動作も確認していました。
>Field変更後、先ほど正常動作を確認しました)

>画像のデータベース登録処理(正常動作部分)
>タイマーイベントでデジカメカードを認識させてから、下記のブロックを実行させます。
procedure TForm1.autosetClick(Sender: TObject);
var
  sr:TSearchRec;
  res:integer;
begin
  if not sw1  then
    exit;
  //デジカメカード認識時処理
  with datamodule7 do begin
     try
      if not directoryexists(s2 + '\' + s4) then //指定したフォルダがないか検索
      createdir(s2 + '\' + s4) else begin end;   //無ければ作る
      res := findfirst(s1 + '\*.JPG',faAnyfile,sr); //ファイル検索開始

      table1.edit;
      while res = 0 do
      begin

        table1.FieldByName('フォルダ名').AsString := s2 + '\'+ s4;
        table1.FieldByName('ファイル名').AsString := sr.Name;
        table1.FieldByName('ナンバー').AsString := S4;
        table1.FieldByName('撮影日時').AsString := datetimetostr(FileDateToDateTime(fileage(S1 + '\' + sr.Name)));
        table1.FieldByName('物件名').AsString := s5;
        table1.FieldByName('場所').AsString := s7 + '\' + s5;

        table1.post;
        table1.Append;
        copyfile(allocpchar(S1 + '\' +sr.name),allocpchar(s2 + '\'+ s4 + '\' + sr.name), false);
        res := findnext(sr);

      end;

      findclose(sr);
    except

     end;
    StrDispose(ps);
    s5 := '物件名';
  end;

end;

になります。

改めて自分のコード見ると、書き込みミスや勘違い設定が多いですね・・・;
かなりの長文になってしまい恐縮ですが、よろしくお願いしますm(__)m。


Delphi大好き  2009-05-16 02:10:55  No: 34394

判りました!
完全な自分の考え違いでした;;

フォルダごとドラックドロップするのではなく、
ファイルを直接ドロップするのを、
フォルダごとドロップするのと勘違いしていました;

早速フォルダごと処理するコードに書き換えたいと思います。

思い違いですいませんでした;
それではありがとうございましたm(__)m。


Delphi大好き  2009-05-19 01:29:23  No: 34395

コード完成しました。
フォルダごと投げ入れるのと、
ファイルごとに処理するのを、両方組み込んで、
最終的には以下のコードになりました。
igyさんありがとうございました。

procedure TForm1.WMDropFiles(var Msg: TWMDropFiles);
var
  FileName: array [0..255] of Char;
  I, Num: Word;
  sr:tsearchrec;
  res:integer;

begin
   DragQueryFile(Msg.Drop, 0, FileName, SizeOf(FileName));
  if '.jpg' = extractfileext(extractfilename(strpas(FileName)))then  
  begin
    //ファイルごとドロップした時の処理
    DragQueryFile(Msg.Drop, 0, FileName, SizeOf(FileName));
    s8 := extractfilepath(strpas(FileName)) + '\';
    form12.ShowModal;//ドロップしたファイル一覧のプリヴューウインドウ表示
    if InputQuery('写真の物件名を', '入力してください', s5) then
    else
      exit;

      Num := DragQueryFile(Msg.Drop, $FFFFFFFF, nil, 0);
      with datamodule7.table1 do begin
        last;
        s4 := FieldByName('ナンバー').AsString;
        s4 := inttostr(FieldByName('ナンバー').AsInteger + 1);
        
        append;
        edit;
        

        if not directoryexists(s2 + '\' + s4) then //指定したフォルダがないか検索
          createdir(s2 + '\' + s4) else begin end;   //無ければ作る

        for I := 0 to Num - 1 do begin
          DragQueryFile(Msg.Drop, I, FileName, SizeOf(FileName));

          FieldByName('フォルダ名').AsString := s2 + '\'+ s4;
          FieldByName('ファイル名').AsString := extractfilename(strpas(FileName));
          FieldByName('ナンバー').AsString := S4;
          FieldByName('撮影日時').AsString := datetimetostr(FileDateToDateTime(fileage(strpas(filename))));
          FieldByName('物件名').AsString := s5;
          FieldByName('場所').AsString := extractfiledir(strpas(filename));
          post;

          copyfile(filename,allocpchar(s2 + '\'+ s4 + '\' + extractfilename(filename)), false);

          Append;
      end;
    end;
   DragFinish(Msg.Drop);
  s5 := '物件名';
  exit;
  end;

  //フォルダごとドロップした時の処理

    DragQueryFile(Msg.Drop, 0, FileName, SizeOf(FileName));
    s8 := strpas(FileName) + '\';
    form12.ShowModal;
    s5 := extractfilename(strpas(FileName));
    if InputQuery('写真の物件名を', '入力してください', s5) then
      else
      exit;

  { ドロップされたファイル名の取得 }
    count1 := 0;
    memo2.Lines.Clear;
    DragQueryFile(Msg.Drop, 0, FileName, SizeOf(FileName));
    res := findfirst(filename + '\*.jpg',faAnyFile,sr);
      datamodule7.table1.last;
      s4 := datamodule7.table1.FieldByName('ナンバー').AsString;
      s4 := inttostr(datamodule7.table1.FieldByName('ナンバー').AsInteger + 1);
      datamodule7.table1.Append;
      datamodule7.table1.edit;
      
      if not directoryexists(s2 + '\' + s4) then //指定したフォルダがないか検索
        createdir(s2 + '\' + s4) else begin end;   //無ければ作る
      while res = 0 do begin
        memo2.Lines.Add(strpas(FileName) +'\'+sr.Name);
        res := findnext(sr);

        with datamodule7.table1 do begin
          FieldByName('フォルダ名').AsString := s2 + '\'+ s4;
          FieldByName('ファイル名').AsString := extractfilename(memo2.Lines[count1]);
          FieldByName('ナンバー').AsString := S4;
          FieldByName('撮影日時').AsString := datetimetostr(FileDateToDateTime(fileage(memo2.Lines[count1])));

          FieldByName('物件名').AsString := s5;
          FieldByName('場所').AsString := strpas(FileName);
          post;
          Append;
          copyfile(allocpchar(memo2.Lines[count1]),allocpchar(s2 + '\'+ s4 + '\' + extractfilename(memo2.Lines[count1])), false);

          count1 := count1 + 1;
      end;
    end;
    findclose(sr);
    sw5 := true;
    { ドロップ処理の終了 }
    DragFinish(Msg.Drop);
    StrDispose(ps);
    s5 := '物件名';
end;

長文なってしまいまいすいません^^;
igyのおかげで、書いた処理内容思い出しました^^。
今回もありがとうございましたm(__)m。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加