SCRename奮闘記
本来ならカテゴリ「プログラミング(ゲーム以外) [VBScript]」と書きたいところですが、自分で生み出した物の話ではないので、「日常」カテゴリに書こうと思います。
私は録画したテレビのファイル名変更を"どろラッコ"さんから教えていただいた「SCRename」というバッチ+スクリプトを使って自動的に「番組名+話数+タイトル+放送局」みたいな感じでリネームしているのですが、このスクリプトが私のビデオサーバであるWindows 7 64bit版環境では動かない… …正確にはエラーが発生してしまう状況となっていました。
しかし、Windows XP 32bit版/Windows Vista 32bit版では問題なく動作する事、"どろラッコ"さんのWindows 7 64bit版では動作する事から、「わいのビデオサーバで動かなけりゃ意味がないんや! こうなりゃヤケノヤンパチや!! スクリプトなんてたかがクソ言語だっ!めった刺しにしてやるんや~! (`@3@´)」と、本格的に追うことにしました…
普段書く事なんて無い言語なのに… イラッ☆
私は録画したテレビのファイル名変更を"どろラッコ"さんから教えていただいた「SCRename」というバッチ+スクリプトを使って自動的に「番組名+話数+タイトル+放送局」みたいな感じでリネームしているのですが、このスクリプトが私のビデオサーバであるWindows 7 64bit版環境では動かない… …正確にはエラーが発生してしまう状況となっていました。
しかし、Windows XP 32bit版/Windows Vista 32bit版では問題なく動作する事、"どろラッコ"さんのWindows 7 64bit版では動作する事から、「わいのビデオサーバで動かなけりゃ意味がないんや! こうなりゃヤケノヤンパチや!! スクリプトなんてたかがクソ言語だっ!めった刺しにしてやるんや~! (`@3@´)」と、本格的に追うことにしました…
普段書く事なんて無い言語なのに… イラッ☆
ということで、まずは「どのように、このプログラム(スクリプト)ができているのか」を追いました。
SCRenameはバッチファイルになっていて、そこから実行環境引数のファイル名をcscript(Windows Script Host)を使って、VBScriptを実行している…という仕様でした。
そして、次に「どこがエラーになっている?」から考えました。実はこの現象は大分前に遭遇していて、スクリプトをちょっとgrepしていたりしました。結果としてはCreateObjectにてエラーが発生していました。これのエラーはCOM(ActiveX, OCX, DLL)のロードエラーが大半なので、最初見た時は「ランタイムが無いのかな?」なんて思っていたのですが、ここのところWindows Updateやらなにやら、やたらとOSが煩かったので、根負けして新しいものをかなり入れまくり、一般的なランタイムというランタイムを全てインストールして、これらを最新にしました。
…が、この現象は変わりませんでした。
ちなみに発生したエラーはこのような感じです。
「Msxml2.XMLHTTP オブジェクトを作成できませんでした。」
MSXMLはXMLパーサ等の機能が含まれており、マイクロソフト製品のインターネット処理では重要な部分を持っている物という見解だったので、これがインストールされてない訳はないな…と思い、Windowsディレクトリ直下を検索したら、普通に見つかりました。それも当然Msxml2だけでは無く、3, 6などゴロゴロと…
「それでは、なぜロードができないのか?」ということで、チョンプロ(サンプルプログラム)を書いてみることに…
「CreateObjectで、XMLパーサがロードできた!」
うはwww なんだよ。 …ってことは、SCRenameのバグなんじゃねーか?…と。
仕方ないので、嫌々ソースを追うことに…
「コメントが殆ど無い… 汚ったねー!」と愕然としながら、問題のCreateObjectの部分に行きました。
「あれれ? 文法的には問題ないな… これなら俺が書いたサンプルでもロードができた訳だ…」
しかし、ソースが汚いので、変数の設定等が分かり辛いです。これはどんな人が作ったんだろう… 保守とかあまり経験ない人か、引継ぎの経験が乏しい、もしくは集団でコードを書いた事がない人なのかも…と色々とプロファイリングしながらも、この部分が悪さをしているのに、サンプルでは問題なく実行できる…と思い、「まずはCreateObjectを最初にやってしまい、サンプルのように最初からロードができるか実験をしてみよう。」と考え、コードを先頭に移動しました。作りとしてはラストの方でロードしていましたが、別段先頭でも問題ない… むしろこのようなオブジェクトが最初から作れないと本末転倒なので、最初にやっておけばいいのに…位思いました。
そして、先頭にてXMLパーサをCreateObjectしてみたところ…
「で、できた…」
よく分かりませんが、できました。ということは、途中で内部の情報が破壊されてるって事…なのですが、こんな超高級言語でそんな事できるものなのか…?なんて思いましたが、データ型が曖昧な言語なので、データ破壊というよりは作った人間が途中で変数の意味が曖昧になり、ブッ壊しちゃんたんだろう…位思うようにしました。
「CreateObjectもできた事だし、今度こそ上手くいくだろう…」と、喜んで実行してみたところ、
「フォルダ ) を作成できませんでした。」
「??? は? なんじゃこりゃ。 もうアホか?」と。「これはもっと違う次元でエラーが起きたな…」とコーディング歴30年の経験則が脳裏をよぎりました。
「これは、もうちゃんと追うか… たかが1K Stepもないソースだ。本気出せばどうにかなるかな…」と思い、今度は本気で追いました。
大枠はシンプルに作ってあるお陰で、10分位で概要のアルゴリズムは理解できました。「なるほど、なるほど、よく出来るなぁ~」と結構感心しました。このプログラムは「しょぼいカレンダー」というサイトのデータを元にファイル名のリネームを行っているのですが、よく練られています。しかしそのような素晴らしいプログラムでも、私の64bit環境で動かなければ全く意味がありません。絵に描いた餅です…
なんとなく追っていると、「あ~。ここをErr.Numberに頼ってるのね… これは場合により依存するかな…」と思い、ちょっと細工をしました。
「おぉ~、ダイジョブ。ちゃんと動くようになった♪」
ということで、平日だというのに、趣味のサンデープログラミングをやりました。
あまり平日はプログラミングしないようにしていたのですが、やけになったらトコトン全力です。重い腰がなかなか上がらない性格なのですが、不便な時はしょうがなく頑張ります。
ということで、ゲームする時間が無くなりました。
(それも、こんなクソ日記書いている時点で、更に無駄なのですがw)
しかし、ちゃんと動くと凄く使えます。SCRename…
作ってくれた方に感謝いたします。ありがとうございます。m(_ _)m
SCRenameはバッチファイルになっていて、そこから実行環境引数のファイル名をcscript(Windows Script Host)を使って、VBScriptを実行している…という仕様でした。
そして、次に「どこがエラーになっている?」から考えました。実はこの現象は大分前に遭遇していて、スクリプトをちょっとgrepしていたりしました。結果としてはCreateObjectにてエラーが発生していました。これのエラーはCOM(ActiveX, OCX, DLL)のロードエラーが大半なので、最初見た時は「ランタイムが無いのかな?」なんて思っていたのですが、ここのところWindows Updateやらなにやら、やたらとOSが煩かったので、根負けして新しいものをかなり入れまくり、一般的なランタイムというランタイムを全てインストールして、これらを最新にしました。
…が、この現象は変わりませんでした。
ちなみに発生したエラーはこのような感じです。
MSXMLはXMLパーサ等の機能が含まれており、マイクロソフト製品のインターネット処理では重要な部分を持っている物という見解だったので、これがインストールされてない訳はないな…と思い、Windowsディレクトリ直下を検索したら、普通に見つかりました。それも当然Msxml2だけでは無く、3, 6などゴロゴロと…
「それでは、なぜロードができないのか?」ということで、チョンプロ(サンプルプログラム)を書いてみることに…
うはwww なんだよ。 …ってことは、SCRenameのバグなんじゃねーか?…と。
仕方ないので、嫌々ソースを追うことに…
「コメントが殆ど無い… 汚ったねー!」と愕然としながら、問題のCreateObjectの部分に行きました。
「あれれ? 文法的には問題ないな… これなら俺が書いたサンプルでもロードができた訳だ…」
しかし、ソースが汚いので、変数の設定等が分かり辛いです。これはどんな人が作ったんだろう… 保守とかあまり経験ない人か、引継ぎの経験が乏しい、もしくは集団でコードを書いた事がない人なのかも…と色々とプロファイリングしながらも、この部分が悪さをしているのに、サンプルでは問題なく実行できる…と思い、「まずはCreateObjectを最初にやってしまい、サンプルのように最初からロードができるか実験をしてみよう。」と考え、コードを先頭に移動しました。作りとしてはラストの方でロードしていましたが、別段先頭でも問題ない… むしろこのようなオブジェクトが最初から作れないと本末転倒なので、最初にやっておけばいいのに…位思いました。
そして、先頭にてXMLパーサをCreateObjectしてみたところ…
よく分かりませんが、できました。ということは、途中で内部の情報が破壊されてるって事…なのですが、こんな超高級言語でそんな事できるものなのか…?なんて思いましたが、データ型が曖昧な言語なので、データ破壊というよりは作った人間が途中で変数の意味が曖昧になり、ブッ壊しちゃんたんだろう…位思うようにしました。
「CreateObjectもできた事だし、今度こそ上手くいくだろう…」と、喜んで実行してみたところ、
「??? は? なんじゃこりゃ。 もうアホか?」と。「これはもっと違う次元でエラーが起きたな…」とコーディング歴30年の経験則が脳裏をよぎりました。
「これは、もうちゃんと追うか… たかが1K Stepもないソースだ。本気出せばどうにかなるかな…」と思い、今度は本気で追いました。
大枠はシンプルに作ってあるお陰で、10分位で概要のアルゴリズムは理解できました。「なるほど、なるほど、よく出来るなぁ~」と結構感心しました。このプログラムは「しょぼいカレンダー」というサイトのデータを元にファイル名のリネームを行っているのですが、よく練られています。しかしそのような素晴らしいプログラムでも、私の64bit環境で動かなければ全く意味がありません。絵に描いた餅です…
なんとなく追っていると、「あ~。ここをErr.Numberに頼ってるのね… これは場合により依存するかな…」と思い、ちょっと細工をしました。
ということで、平日だというのに、趣味のサンデープログラミングをやりました。
あまり平日はプログラミングしないようにしていたのですが、やけになったらトコトン全力です。重い腰がなかなか上がらない性格なのですが、不便な時はしょうがなく頑張ります。
ということで、ゲームする時間が無くなりました。
(それも、こんなクソ日記書いている時点で、更に無駄なのですがw)
しかし、ちゃんと動くと凄く使えます。SCRename…
作ってくれた方に感謝いたします。ありがとうございます。m(_ _)m
コメント
No title
No title
ちなみに4行目の
On Error Resume Next
を削除すれば、本当のエラーの箇所がわかるはずです。
もう必要ないとは思いますが。
On Error Resume Next
を削除すれば、本当のエラーの箇所がわかるはずです。
もう必要ないとは思いますが。
回答いたします
SCR作者様
初めまして、このブログを書いているOKIです。
まず最初に言わせてください。
「ブログにて色々と好き勝手書いてしまい、気分を害しているようでしたら大変申し訳ございません。
そして非常に使い勝手の良いプログラム、本当にありがとうございます。」
さて、プログラムの方の回答ですが、以下のとおりとなります。
尚、SCRenameはVer 4.8を基に説明させて頂きます。
>場合により依存する
これはプラットフォームの時刻情報のフォーマットに起因します。
SCR作者様の時刻フォーマットは恐らく「yyyy/mm/dd hh24:mi:ss」となっていると思いますが、私のWindows 7 64bit環境では、
「yyyy/mm/dd (aaa) hh24:mi:ss」となっています。(aaaはExcelに合わせて曜日です)
具体的に、Windows XP Professional 32bit SP3 環境では、
WScript.StdOut.WriteLine now() -> 2011/11/03 0:54:40
Windows 7 Home Premium 64bit SP1 環境では、
WScript.StdOut.WriteLine now() -> 2011/11/03 (木) 0:54:40
と出力されます。
>個人的には239行目の
>dt2=CDate(objFSO.GetFile(argv(0)).DateLastModified)
>あたりかなと推察しております。
残念ながら、
C:SCRename.vbs(403, 1) Microsoft VBScript 実行時エラー: 型が一致しません。: 'DateValue'
です。これは上述に関連しています。
内部処理を細かく追ってはいないのですが、文字列処理に違いが発生する事があるかと思っております。
実は日記では、少しゴマかして書いたのですが(この日記の趣旨で小難しい事書いても誰も反応できないのは分かっているので)、先ず最初に「On Error Resume Next」を外しました。
それで「Set objHTTP=CreateObject("Msxml2.XMLHTTP")」の前ではなく、その前でオブジェクトが破壊されている事を推測し、自前なりに解釈した改修を行いました。
>バグを発見することがありましたら2chの「TS関連ソフトウェア総合スレ」へ
>ご報告いただければ助かります。
申し訳ございません。
私の方諸事情により、「2chに書きこむ事に拒絶反応を持っております」ので、その辺りは対応できません。
こうしてブログにてコミュニケーションが取れた事を非常に嬉しく思っております。
このような回答でよろしいでしょうか?
◇ ◇ ◇
繰り返しますが、好き勝手書かせていただき、お気を悪くされていたら大変申し訳ございません。
SCRenameは非常に重宝しており、毎日のようにバックグランドで走らせております。
このような実用的で価値のあるプログラムをご提供いただき、誠にありがとうございます。
以上です。
初めまして、このブログを書いているOKIです。
まず最初に言わせてください。
「ブログにて色々と好き勝手書いてしまい、気分を害しているようでしたら大変申し訳ございません。
そして非常に使い勝手の良いプログラム、本当にありがとうございます。」
さて、プログラムの方の回答ですが、以下のとおりとなります。
尚、SCRenameはVer 4.8を基に説明させて頂きます。
>場合により依存する
これはプラットフォームの時刻情報のフォーマットに起因します。
SCR作者様の時刻フォーマットは恐らく「yyyy/mm/dd hh24:mi:ss」となっていると思いますが、私のWindows 7 64bit環境では、
「yyyy/mm/dd (aaa) hh24:mi:ss」となっています。(aaaはExcelに合わせて曜日です)
具体的に、Windows XP Professional 32bit SP3 環境では、
WScript.StdOut.WriteLine now() -> 2011/11/03 0:54:40
Windows 7 Home Premium 64bit SP1 環境では、
WScript.StdOut.WriteLine now() -> 2011/11/03 (木) 0:54:40
と出力されます。
>個人的には239行目の
>dt2=CDate(objFSO.GetFile(argv(0)).DateLastModified)
>あたりかなと推察しております。
残念ながら、
C:SCRename.vbs(403, 1) Microsoft VBScript 実行時エラー: 型が一致しません。: 'DateValue'
です。これは上述に関連しています。
内部処理を細かく追ってはいないのですが、文字列処理に違いが発生する事があるかと思っております。
実は日記では、少しゴマかして書いたのですが(この日記の趣旨で小難しい事書いても誰も反応できないのは分かっているので)、先ず最初に「On Error Resume Next」を外しました。
それで「Set objHTTP=CreateObject("Msxml2.XMLHTTP")」の前ではなく、その前でオブジェクトが破壊されている事を推測し、自前なりに解釈した改修を行いました。
>バグを発見することがありましたら2chの「TS関連ソフトウェア総合スレ」へ
>ご報告いただければ助かります。
申し訳ございません。
私の方諸事情により、「2chに書きこむ事に拒絶反応を持っております」ので、その辺りは対応できません。
こうしてブログにてコミュニケーションが取れた事を非常に嬉しく思っております。
このような回答でよろしいでしょうか?
◇ ◇ ◇
繰り返しますが、好き勝手書かせていただき、お気を悪くされていたら大変申し訳ございません。
SCRenameは非常に重宝しており、毎日のようにバックグランドで走らせております。
このような実用的で価値のあるプログラムをご提供いただき、誠にありがとうございます。
以上です。
No title
ご返答ありがとうございます。
以前に使用者の方から要望頂いたことを盛り込んで、久しぶりにSCRenameを改修しようと思い立ち、どうせならと他の使用者の方の使用感などを求めてgoogleで検索したところ、ちょうどこのBlogにたどり着いた次第です。
期せずしてバグが発見できたことをうれしく思っております。ですので気分を害すことなどありませんのでご安心ください。
むしろ、ソースをタイトにしすぎたために他人には非常にわかりにくくなっているにも関わらず、解析して頂きありがとうございます。
ロケールの違い等は考慮に入れたつもりだったのですが検証が不十分でした。できましたら変更の箇所と内容を、後学のためにご教示頂けたらうれしく存じます。
以前に使用者の方から要望頂いたことを盛り込んで、久しぶりにSCRenameを改修しようと思い立ち、どうせならと他の使用者の方の使用感などを求めてgoogleで検索したところ、ちょうどこのBlogにたどり着いた次第です。
期せずしてバグが発見できたことをうれしく思っております。ですので気分を害すことなどありませんのでご安心ください。
むしろ、ソースをタイトにしすぎたために他人には非常にわかりにくくなっているにも関わらず、解析して頂きありがとうございます。
ロケールの違い等は考慮に入れたつもりだったのですが検証が不十分でした。できましたら変更の箇所と内容を、後学のためにご教示頂けたらうれしく存じます。
Re: 回答いたします (Take2)
こんばんわ。
>google検索
本当ですね… 結構上位に出てきてビックリです。
何気に本ブログの訪問者数(リピート訪問者数)が多いので、本ブログの検索スコアが上がっているみたいですね…
(googleの検索インデックス更新はニュースやブログを優先的にクロールしているので、それが仇になりました)
>期せずしてバグが発見できたことをうれしく思っております。
>ですので気分を害すことなどありませんのでご安心ください。
ありがとうございます。そう言っていただけると恐縮です。
>解析して頂きありがとうございます。
こちらこそリバースエンジニアリングまがいな事をしてしまい、大変失礼いたしました。
>ロケールの違い等は考慮に入れたつもりだったのですが検証が不十分でした。
>できましたら変更の箇所と内容を、後学のためにご教示頂けたらうれしく存じます。
本件ですが、まず先にお伝えしておくことがございます。
本件は私なりの改修を行った後に、本日記を書いたのですが、その後再度ネット上でオリジナルを入手した(元々本プログラムは人経由で頂いたものでした)という経緯があり、その際に最新バージョンのものを上書きし、修正した箇所のソースは削除してしまいました。
しかし、その時の最新バージョンでも現象はWindows 7上にて再現されてしまい、仕方なく現在はそれから「簡略に修正をしてもの」を使用しています。
「簡略」なので日記に書いたようにCreateObjectの生成位置を前方に移動しつつ、On Error Resume Nextは有効にしたまま(Windows 7上で文法が違っていても爆走させる)で、Err.Numberにて判定している箇所を無視する…という版を作り直しました。
つまり文字列操作の問題はそのままスルーさせて、その後それでも進められる事を検証した版として使用しています。(一応動くようです。しかし、On Error Resume Nextを外すとたちまちDateValueの例外が発生します)
それでよろしければ、diffを取りましたので以下に記載しておきます。
$ diff SCRename.vbs SCRename.vbs.mod
24a25,32
> Set objHTTP=CreateObject("Microsoft.XmlHttp")
> If Err.Number<>0 Then
> WScript.Echo argv(0)
> WScript.StdErr.WriteLine "Msxml2.XMLHTTP オブジェクトを作成できませんでした。"
> WScript.Sleep(1000)
> WScript.Quit(1)
> End If
>
412,418c420,427
< Set objHTTP=CreateObject("Msxml2.XMLHTTP")
< If Err.Number<>0 Then
< WScript.Echo argv(0)
< WScript.StdErr.WriteLine "Msxml2.XMLHTTP オブジェクトを作成できませんでした。"
< WScript.Sleep(1000)
< WScript.Quit(1)
< End If
---
> 'Set objHTTP=CreateObject("Msxml2.XMLHTTP")
> 'Set objHTTP=CreateObject("Microsoft.XmlHttp")
> 'If Err.Number<>0 Then
> ' WScript.Echo argv(0)
> ' WScript.StdErr.WriteLine "Msxml2.XMLHTTP オブジェクトを作成できませんでした。"
> ' WScript.Sleep(1000)
> ' WScript.Quit(1)
> 'End If
437a447
>
838a849
> Err.Number = 0
842c853
< If i>1 Then
---
> If i > 1 Then
改めてdiffを取ると、ActiveXのロード位置に少し試行錯誤した後があり、似たようなdiffが取れてしまってますね…
これでは暴力的なので、私が使っているものを以下にアップロードしておきますので、これを参考にしていただけると幸いです。
http://goo.gl/Qq2r3
修正内容の議論は本ブログではニュアンスが伝わりづらいので、割愛させていただけると幸いです。
SCR作者様の本プログラミングにかけるコーディングポリシーの意図、並びにプログラミングスキルの"詳細"が私には分かりかねておりますので、恐らくこのような匿名性の強い場所では見解が100%ズレると判断しております。(過去にそのような事が本ブログで多数あり、全て無駄な時間を費やしました…)
もしも調査をされるのであれば、now()の出力形式を洗いざらい確認…といったところでしょう。
少なくとも一つ前のコメントにて「yyyy/mm/dd (aaa) hh24:mi:ss」のフォーマットで返る環境がある訳ですので、この文字列が来た場合のケースでコーディングされると良いかと思います。
SCR作者様の開発環境にWindows 7 64bit環境がございましたら、ご確認いただけると幸いです。
日記にも書いたのですが、別の方のWindows 7 64bit版では現象が発生していないので、何か設定がある可能性がございます。(ちなみに私は特にロケールの設定は編集しておりません。何故XP等と違うのかは調査しないとなりませんが、その時間を割くのはご勘弁いただきたいところです)
以上です。
>google検索
本当ですね… 結構上位に出てきてビックリです。
何気に本ブログの訪問者数(リピート訪問者数)が多いので、本ブログの検索スコアが上がっているみたいですね…
(googleの検索インデックス更新はニュースやブログを優先的にクロールしているので、それが仇になりました)
>期せずしてバグが発見できたことをうれしく思っております。
>ですので気分を害すことなどありませんのでご安心ください。
ありがとうございます。そう言っていただけると恐縮です。
>解析して頂きありがとうございます。
こちらこそリバースエンジニアリングまがいな事をしてしまい、大変失礼いたしました。
>ロケールの違い等は考慮に入れたつもりだったのですが検証が不十分でした。
>できましたら変更の箇所と内容を、後学のためにご教示頂けたらうれしく存じます。
本件ですが、まず先にお伝えしておくことがございます。
本件は私なりの改修を行った後に、本日記を書いたのですが、その後再度ネット上でオリジナルを入手した(元々本プログラムは人経由で頂いたものでした)という経緯があり、その際に最新バージョンのものを上書きし、修正した箇所のソースは削除してしまいました。
しかし、その時の最新バージョンでも現象はWindows 7上にて再現されてしまい、仕方なく現在はそれから「簡略に修正をしてもの」を使用しています。
「簡略」なので日記に書いたようにCreateObjectの生成位置を前方に移動しつつ、On Error Resume Nextは有効にしたまま(Windows 7上で文法が違っていても爆走させる)で、Err.Numberにて判定している箇所を無視する…という版を作り直しました。
つまり文字列操作の問題はそのままスルーさせて、その後それでも進められる事を検証した版として使用しています。(一応動くようです。しかし、On Error Resume Nextを外すとたちまちDateValueの例外が発生します)
それでよろしければ、diffを取りましたので以下に記載しておきます。
$ diff SCRename.vbs SCRename.vbs.mod
24a25,32
> Set objHTTP=CreateObject("Microsoft.XmlHttp")
> If Err.Number<>0 Then
> WScript.Echo argv(0)
> WScript.StdErr.WriteLine "Msxml2.XMLHTTP オブジェクトを作成できませんでした。"
> WScript.Sleep(1000)
> WScript.Quit(1)
> End If
>
412,418c420,427
< Set objHTTP=CreateObject("Msxml2.XMLHTTP")
< If Err.Number<>0 Then
< WScript.Echo argv(0)
< WScript.StdErr.WriteLine "Msxml2.XMLHTTP オブジェクトを作成できませんでした。"
< WScript.Sleep(1000)
< WScript.Quit(1)
< End If
---
> 'Set objHTTP=CreateObject("Msxml2.XMLHTTP")
> 'Set objHTTP=CreateObject("Microsoft.XmlHttp")
> 'If Err.Number<>0 Then
> ' WScript.Echo argv(0)
> ' WScript.StdErr.WriteLine "Msxml2.XMLHTTP オブジェクトを作成できませんでした。"
> ' WScript.Sleep(1000)
> ' WScript.Quit(1)
> 'End If
437a447
>
838a849
> Err.Number = 0
842c853
< If i>1 Then
---
> If i > 1 Then
改めてdiffを取ると、ActiveXのロード位置に少し試行錯誤した後があり、似たようなdiffが取れてしまってますね…
これでは暴力的なので、私が使っているものを以下にアップロードしておきますので、これを参考にしていただけると幸いです。
http://goo.gl/Qq2r3
修正内容の議論は本ブログではニュアンスが伝わりづらいので、割愛させていただけると幸いです。
SCR作者様の本プログラミングにかけるコーディングポリシーの意図、並びにプログラミングスキルの"詳細"が私には分かりかねておりますので、恐らくこのような匿名性の強い場所では見解が100%ズレると判断しております。(過去にそのような事が本ブログで多数あり、全て無駄な時間を費やしました…)
もしも調査をされるのであれば、now()の出力形式を洗いざらい確認…といったところでしょう。
少なくとも一つ前のコメントにて「yyyy/mm/dd (aaa) hh24:mi:ss」のフォーマットで返る環境がある訳ですので、この文字列が来た場合のケースでコーディングされると良いかと思います。
SCR作者様の開発環境にWindows 7 64bit環境がございましたら、ご確認いただけると幸いです。
日記にも書いたのですが、別の方のWindows 7 64bit版では現象が発生していないので、何か設定がある可能性がございます。(ちなみに私は特にロケールの設定は編集しておりません。何故XP等と違うのかは調査しないとなりませんが、その時間を割くのはご勘弁いただきたいところです)
以上です。
No title
詳細なコメントありがとうございます。
ちなみに、私の開発環境もWindows 7 x64 SP1で同一のものです。
>修正内容の議論は本ブログではニュアンスが伝わりづらいので、割愛させていただけると幸いです。
ご丁寧にありがとうございます。
私としては本スクリプトのコーディングポリシーが一般的なものと大分ずれていることは認識しておりますし(今時、数個の変数の確保を躊躇するほどシビアなメモリ環境はあり得ませんし)、単に意図した動作を行わない状況を排除したいというだけですので。
1つだけ確認させて頂きたいのですが、オリジナルからOn Error Resume Nextをコメントアウトした状態でのエラーは
>C:SCRename.vbs(403, 1) Microsoft VBScript 実行時エラー: 型が一致しません。: 'DateValue'
ということ、もっといえばDateValue(tgtdt)における、変数tgtdtが日付型になっていなかったことによるという理解でよろしいでしょうか?
あと、念のためエラーの生じたファイル名(リネームとしたファイル)も教えて頂けますでしょうか。
ちなみに、私の開発環境もWindows 7 x64 SP1で同一のものです。
>修正内容の議論は本ブログではニュアンスが伝わりづらいので、割愛させていただけると幸いです。
ご丁寧にありがとうございます。
私としては本スクリプトのコーディングポリシーが一般的なものと大分ずれていることは認識しておりますし(今時、数個の変数の確保を躊躇するほどシビアなメモリ環境はあり得ませんし)、単に意図した動作を行わない状況を排除したいというだけですので。
1つだけ確認させて頂きたいのですが、オリジナルからOn Error Resume Nextをコメントアウトした状態でのエラーは
>C:SCRename.vbs(403, 1) Microsoft VBScript 実行時エラー: 型が一致しません。: 'DateValue'
ということ、もっといえばDateValue(tgtdt)における、変数tgtdtが日付型になっていなかったことによるという理解でよろしいでしょうか?
あと、念のためエラーの生じたファイル名(リネームとしたファイル)も教えて頂けますでしょうか。
No title
修正を試みましたので下記のファイルを試して頂いてよろしいでしょうか。
http://www1.axfc.net/uploader/Sc/so/289398
On Error Resume Nextをコメントアウトしておりますが、エラーメッセージが出る場合は、コメントアウトを外して、画面上にSCRがどんなエラーを表示をするか教えて頂ければ助かります。
お忙しいところ恐れ入りますが、ご助力頂けましたら幸いです。
http://www1.axfc.net/uploader/Sc/so/289398
On Error Resume Nextをコメントアウトしておりますが、エラーメッセージが出る場合は、コメントアウトを外して、画面上にSCRがどんなエラーを表示をするか教えて頂ければ助かります。
お忙しいところ恐れ入りますが、ご助力頂けましたら幸いです。
残念ながら…
想定通り(?)認識がズレて来ているようですね。
修正内容の議論はあまりしたくないのですが…
こちらからも幾つかご質問させて頂きます。
>ちなみに、私の開発環境もWindows 7 x64 SP1で同一のものです。
これは「エディション」はどれをお使いでしょうか?
ご存知だと思いますが、日本では「Home Premium、Professional、Ultimate」がございます。
私の環境は前回コメントにて回答したとおり、Home Premium環境です。今回の件では同じ64bit環境においてあまり違いはないとは思っておりますが、発生する環境としない環境があるので、それを確認する必要があるかと思います。
次に「WScript.StdOut.WriteLine Now()」の出力フォーマットはご確認されたでしょうか?
(空ファイルに1行書いてそのファイルをcscriptで実行するだけです)
SCR作者様の日付出力フォーマットが不明なので、こちらもどのように回答すべきか悩みます。
>もっといえばDateValue(tgtdt)における、変数tgtdtが日付型に
>なっていなかったことによるという理解でよろしいでしょうか?
DateValueの引数は文字列型ですよね?
(http://goo.gl/5CPAM)
つまりtgtdtが日付型の場合は、VBScriptの自動型変換にて文字列に変換されていると思います。
そしてコメントにて回答したとおり、この文字列が「yyyy/mm/dd (aaa) hh24:mi:ss」にて変換された場合、その文字列フォーマットは、DateValue関数上ではフォーマットエラーになります。
試しに「DateValue("2011/11/04 (金) 21:00:00")」と、空ファイルに1行記述してcscriptで実行してみてください。
例外が発生するかと思います。
次に「DateValue("2011/11/04 21:00:00")」と、空ファイルに1行記述してcscriptで実行してみてください。
正常実行されると思います。
VBScriptはプログラム側から型を曖昧にする仕組みを含んでいるので(しかもベースは全てVariant型)、文字列型なのか日付型なのか曖昧になりやすくて厳しいですね。
>修正を試みましたので下記のファイルを試して頂いてよろしいでしょうか。
ご対応早いですね。
(日中に対応できるということは学生さんでしょうか?それとも今日はお休みとか…)
ということで、先程仕事から帰ってきたので早速試しました。
---------
c:\SCRename>SCRename.bat "C:\201107300730_魔法のプリンセス ミンキーモモ _TOKYO MX.ts"
SCRename 動作中...
c:\SCRename\SCRename.vbs(400, 1) Microsoft VBScript 実行時エラー: 型が一致しません。: 'DateValue'
---------
※ファイル名はネタです。
結果は同じですね。
ちなみに、400行前に標準エラー出力にtgtdtを出力した所、「2011/07/30 (土) 7:30:00」と出力されました。
(2011/07/30は土曜日です)
これで上述の説明と合致いたします。
こちらから疑問文が幾つか出たので、それをクリアすると環境の違いなどが分かってくるので、明瞭化できて良いかと思います。
(結果として私の環境がマイノリティという事だけは理解しております)
以上です。
修正内容の議論はあまりしたくないのですが…
こちらからも幾つかご質問させて頂きます。
>ちなみに、私の開発環境もWindows 7 x64 SP1で同一のものです。
これは「エディション」はどれをお使いでしょうか?
ご存知だと思いますが、日本では「Home Premium、Professional、Ultimate」がございます。
私の環境は前回コメントにて回答したとおり、Home Premium環境です。今回の件では同じ64bit環境においてあまり違いはないとは思っておりますが、発生する環境としない環境があるので、それを確認する必要があるかと思います。
次に「WScript.StdOut.WriteLine Now()」の出力フォーマットはご確認されたでしょうか?
(空ファイルに1行書いてそのファイルをcscriptで実行するだけです)
SCR作者様の日付出力フォーマットが不明なので、こちらもどのように回答すべきか悩みます。
>もっといえばDateValue(tgtdt)における、変数tgtdtが日付型に
>なっていなかったことによるという理解でよろしいでしょうか?
DateValueの引数は文字列型ですよね?
(http://goo.gl/5CPAM)
つまりtgtdtが日付型の場合は、VBScriptの自動型変換にて文字列に変換されていると思います。
そしてコメントにて回答したとおり、この文字列が「yyyy/mm/dd (aaa) hh24:mi:ss」にて変換された場合、その文字列フォーマットは、DateValue関数上ではフォーマットエラーになります。
試しに「DateValue("2011/11/04 (金) 21:00:00")」と、空ファイルに1行記述してcscriptで実行してみてください。
例外が発生するかと思います。
次に「DateValue("2011/11/04 21:00:00")」と、空ファイルに1行記述してcscriptで実行してみてください。
正常実行されると思います。
VBScriptはプログラム側から型を曖昧にする仕組みを含んでいるので(しかもベースは全てVariant型)、文字列型なのか日付型なのか曖昧になりやすくて厳しいですね。
>修正を試みましたので下記のファイルを試して頂いてよろしいでしょうか。
ご対応早いですね。
(日中に対応できるということは学生さんでしょうか?それとも今日はお休みとか…)
ということで、先程仕事から帰ってきたので早速試しました。
---------
c:\SCRename>SCRename.bat "C:\201107300730_魔法のプリンセス ミンキーモモ _TOKYO MX.ts"
SCRename 動作中...
c:\SCRename\SCRename.vbs(400, 1) Microsoft VBScript 実行時エラー: 型が一致しません。: 'DateValue'
---------
※ファイル名はネタです。
結果は同じですね。
ちなみに、400行前に標準エラー出力にtgtdtを出力した所、「2011/07/30 (土) 7:30:00」と出力されました。
(2011/07/30は土曜日です)
これで上述の説明と合致いたします。
こちらから疑問文が幾つか出たので、それをクリアすると環境の違いなどが分かってくるので、明瞭化できて良いかと思います。
(結果として私の環境がマイノリティという事だけは理解しております)
以上です。
No title
検証ありがとうございます。
こちらからの情報が漏れてしまいすみません。
Win7はUltimateです。
またご指摘の通り、「yyyy/mm/dd hh24:mi:ss」のフォーマットです。
学生ではありませんが、今日は仕事が暇だったのでいじってました。
もしかしてOKI様の環境では
ddd=DateValue("2011/07/30")
WScript.echo ddd
の結果が
2011/07/30 (土)
になったりしますでしょうか?
こちらからの情報が漏れてしまいすみません。
Win7はUltimateです。
またご指摘の通り、「yyyy/mm/dd hh24:mi:ss」のフォーマットです。
学生ではありませんが、今日は仕事が暇だったのでいじってました。
もしかしてOKI様の環境では
ddd=DateValue("2011/07/30")
WScript.echo ddd
の結果が
2011/07/30 (土)
になったりしますでしょうか?
色々と調査いたしました
こんばんわ、仕事から帰ってきてから外出してしまい、26:30頃帰宅しました。
>Win7はUltimateです。
>またご指摘の通り、「yyyy/mm/dd hh24:mi:ss」のフォーマットです。
情報のご提示とご確認ありがとうございます。
これで話が進められます。
先程重い腰を上げて、各エディションを調べました。
また、更に重い腰を上げて「言語地域設定」を各種調べました。
Windows XP Professional:yyyy/MM/dd
Windows 7 HomePremium:yyyy/MM/dd' ('ddd')'
Windows 7 Professional:yyyy/MM/dd
Windows 7 Ultimate:yyyy/MM/dd
という結果となりました。
Windows 7 HomePremiumのみ、言語地域設定が違いました。
つきましては私の環境はご質問された「2011/07/30 (土)」になります。
これは私の環境のみインストール時に、この設定になっていたのか、HomePremiumがこの設定なのか、何かのソフトに設定を変更されてしまったかは不明です。…が、少なくとも私はこの設定をいじったことがありません。
そこで、Windows XPの言語地域設定をWindows 7 HomePremiumと同様に設定したところ、本現象が再現できました。DateValue関数にて例外が発生します。
逆にWindows 7 HomePremiumの言語地域設定を「yyyy/mm/dd」にしたところ、問題が解消されました。
従って「yyyy/mm/dd (ddd) hh24:mi:ss」(Excel表記改め曜日はddd)
の場合に、SCRenameは挙動がおかしくなるという検証結果です。
(正確にはDateValue関数がこの形式に対応していない…ですね)
この事から言語地域設定により日付型の文字列変換が上述のフォーマットになるケースがあるので、コーディングによりDateValueの代わりとなる関数を作成するか、日付型に変換する際には確実に「yyyy/mm/dd hh24:mi:ss」のフォーマット文字列に正規化を行う必要があるかもしれません。
例) 引数 hoge = 日付型
Dim str
str = CStr(Year(hoge)) + "/" + CStr(Month(hoge)) + "/" + CStr(Day(hoge)) + " " + CStr(Hour(hoge)) + ":" + CStr(Minute(hoge)) + ":" + CStr(Second(hoge))
という感じでしょうか…
もしくは「制約事項」に倒してしまうのも良いかもしれません。
優しいプログラムにするなら、最初にnow()などで日付文字列のフォーマットチェックを行い、エラーメッセージを出して「日付は"yyyy/mm/dd"に設定してください。」と警告を促すとかもありでしょう。
◇ ◇ ◇
>学生ではありませんが、今日は仕事が暇だったのでいじってました。
ご回答ありがとうございます。
SCR作者様は「非常に紳士的な方」とお見受けいたしました。
(このブログ上で自分勝手で一方通行な方を沢山見てきたので、このような質問に関して律儀にご回答いただけると非常に嬉しい次第です)
◇ ◇ ◇
SCR作者様は、これまでの情報に基づき仕様検討や改良ポイントが色々と検討できるのではないかと思います。
つきましては本件はこれにてクローズとさせていただけると幸いです。
私の低俗な日記から、ここまで話が深く掘り下げられて非常に楽しく思います。
これからも素晴らしいツール開発をされると思いますが、頑張って下さいませ。
私もこのブログ上にて、適当に何か作ったりして行こうと思います。(私の場合はゲーム開発ですかね…)
以上です。
>Win7はUltimateです。
>またご指摘の通り、「yyyy/mm/dd hh24:mi:ss」のフォーマットです。
情報のご提示とご確認ありがとうございます。
これで話が進められます。
先程重い腰を上げて、各エディションを調べました。
また、更に重い腰を上げて「言語地域設定」を各種調べました。
Windows XP Professional:yyyy/MM/dd
Windows 7 HomePremium:yyyy/MM/dd' ('ddd')'
Windows 7 Professional:yyyy/MM/dd
Windows 7 Ultimate:yyyy/MM/dd
という結果となりました。
Windows 7 HomePremiumのみ、言語地域設定が違いました。
つきましては私の環境はご質問された「2011/07/30 (土)」になります。
これは私の環境のみインストール時に、この設定になっていたのか、HomePremiumがこの設定なのか、何かのソフトに設定を変更されてしまったかは不明です。…が、少なくとも私はこの設定をいじったことがありません。
そこで、Windows XPの言語地域設定をWindows 7 HomePremiumと同様に設定したところ、本現象が再現できました。DateValue関数にて例外が発生します。
逆にWindows 7 HomePremiumの言語地域設定を「yyyy/mm/dd」にしたところ、問題が解消されました。
従って「yyyy/mm/dd (ddd) hh24:mi:ss」(Excel表記改め曜日はddd)
の場合に、SCRenameは挙動がおかしくなるという検証結果です。
(正確にはDateValue関数がこの形式に対応していない…ですね)
この事から言語地域設定により日付型の文字列変換が上述のフォーマットになるケースがあるので、コーディングによりDateValueの代わりとなる関数を作成するか、日付型に変換する際には確実に「yyyy/mm/dd hh24:mi:ss」のフォーマット文字列に正規化を行う必要があるかもしれません。
例) 引数 hoge = 日付型
Dim str
str = CStr(Year(hoge)) + "/" + CStr(Month(hoge)) + "/" + CStr(Day(hoge)) + " " + CStr(Hour(hoge)) + ":" + CStr(Minute(hoge)) + ":" + CStr(Second(hoge))
という感じでしょうか…
もしくは「制約事項」に倒してしまうのも良いかもしれません。
優しいプログラムにするなら、最初にnow()などで日付文字列のフォーマットチェックを行い、エラーメッセージを出して「日付は"yyyy/mm/dd"に設定してください。」と警告を促すとかもありでしょう。
◇ ◇ ◇
>学生ではありませんが、今日は仕事が暇だったのでいじってました。
ご回答ありがとうございます。
SCR作者様は「非常に紳士的な方」とお見受けいたしました。
(このブログ上で自分勝手で一方通行な方を沢山見てきたので、このような質問に関して律儀にご回答いただけると非常に嬉しい次第です)
◇ ◇ ◇
SCR作者様は、これまでの情報に基づき仕様検討や改良ポイントが色々と検討できるのではないかと思います。
つきましては本件はこれにてクローズとさせていただけると幸いです。
私の低俗な日記から、ここまで話が深く掘り下げられて非常に楽しく思います。
これからも素晴らしいツール開発をされると思いますが、頑張って下さいませ。
私もこのブログ上にて、適当に何か作ったりして行こうと思います。(私の場合はゲーム開発ですかね…)
以上です。
No title
詳しいご解説、心より感謝致します。
原因が特定できました。
非常にシンプルな問題で、やはり
Dim aaa,bbb
aaa=DateValue("2011/07/30")
bbb=DateValue(aaa)
のコードでは「aaa」が「2011/07/30 (土)」に
なってしまうため、3行目がエラーになるのが
原因でした。
今までご助力頂きまして心よりお礼申し上げます。
検証して最新版をアップしたいと思います。
もし、機能の追加の要望等ありましたらお気軽に
ご連絡頂けたらと存じます。
OKI様の作られるゲーム陰ながら楽しみにしております。
原因が特定できました。
非常にシンプルな問題で、やはり
Dim aaa,bbb
aaa=DateValue("2011/07/30")
bbb=DateValue(aaa)
のコードでは「aaa」が「2011/07/30 (土)」に
なってしまうため、3行目がエラーになるのが
原因でした。
今までご助力頂きまして心よりお礼申し上げます。
検証して最新版をアップしたいと思います。
もし、機能の追加の要望等ありましたらお気軽に
ご連絡頂けたらと存じます。
OKI様の作られるゲーム陰ながら楽しみにしております。
原因が特定できて何よりです
こんにちは。
>原因が特定できました。
>「2011/07/30 (土)」に
>なってしまうため、3行目がエラーになるのが
>原因でした。
はい、一番最初から申しているように、「時刻情報のフォーマットに起因(場合により依存)」しております。
>もし、機能の追加の要望等ありましたらお気軽に
>ご連絡頂けたらと存じます。
これは最初に申し上げたとおり、
>申し訳ございません。
>私の方諸事情により、「2chに書きこむ事に
>拒絶反応を持っております」ので、その辺りは対応できません。
ですので、現状は無理かと思います。
(SCR作者様がホームページ等を所有しており、そこに掲示板またはメールアドレスでもあれば別なのですが…)
◇ ◇ ◇
今回の件で私の方も非常にためになりました。
今回の件を通して学習した事は、
1.ブログに下手なことを書くと、自他ともそのリスクを追う。
2.場合により「1」は楽しい作業にもなる。
3.やはりテキストコミュニケーションは言葉での意思疎通には敵わない。
4.本ブログにて、SCR作者様のように「プログラミングに対して情熱を持った方」
とやりとりが行える。
という事です。
私の低俗な戯言を契機に色々とお付き合いありがとうございます。
以上です。
>原因が特定できました。
>「2011/07/30 (土)」に
>なってしまうため、3行目がエラーになるのが
>原因でした。
はい、一番最初から申しているように、「時刻情報のフォーマットに起因(場合により依存)」しております。
>もし、機能の追加の要望等ありましたらお気軽に
>ご連絡頂けたらと存じます。
これは最初に申し上げたとおり、
>申し訳ございません。
>私の方諸事情により、「2chに書きこむ事に
>拒絶反応を持っております」ので、その辺りは対応できません。
ですので、現状は無理かと思います。
(SCR作者様がホームページ等を所有しており、そこに掲示板またはメールアドレスでもあれば別なのですが…)
◇ ◇ ◇
今回の件で私の方も非常にためになりました。
今回の件を通して学習した事は、
1.ブログに下手なことを書くと、自他ともそのリスクを追う。
2.場合により「1」は楽しい作業にもなる。
3.やはりテキストコミュニケーションは言葉での意思疎通には敵わない。
4.本ブログにて、SCR作者様のように「プログラミングに対して情熱を持った方」
とやりとりが行える。
という事です。
私の低俗な戯言を契機に色々とお付き合いありがとうございます。
以上です。
コメントの投稿
「メモリをなるべくつかわない」という意味不明なポリシーのために変数はできるだけ使い回しており、また「サブルーチンも使用しない」ことにしているため、かなり見づらくなっています。
さて、今回の不具合ですが、ご存じの通り
Set objHTTP=CreateObject("Msxml2.XMLHTTP")
の前のどこかでエラーが起きていることに起因していると思います。
「場合により依存する」ということでしたが、詳細を教えて頂けませんでしょうか。
個人的には239行目の
dt2=CDate(objFSO.GetFile(argv(0)).DateLastModified)
あたりかなと推察しております。
また、バグを発見することがありましたら2chの「TS関連ソフトウェア総合スレ」へ
ご報告いただければ助かります。