いりや さん 2004年 05月 19日 16時 54分 50秒

kenji さん、

やり方は一つじゃないんだろうなぁと思いますが、とりあえず Scripting.Dictionary を使った例です。
実行前に全角スペースは取り除いておいてください。

Set WshNet = CreateObject("Wscript.Network")
Set mapTable = CreateObject("Scripting.Dictionary")

initialize(mapTable)
print(mapTable)
'' add(mapTable)
'' remove(mapTable)

Sub initialize(mapTable)
    mapTable.Add "G:", "\\server\dir_1"
    mapTable.add "H:", "\\server\dir_2"
    mapTable.add "I:", "\\server\dir_3"
End Sub

Sub print(mapTable)
    For Each localname In mapTable
        remotename = mapTable.item(localname)
        WScript.Echo(remotename)
    Next
End Sub

Sub add(mapTable)
    For Each localname In mapTable
        remotename = mapTable.item(localname)
        WshNet.MapNetworkDrive localname, remotename
    Next
End Sub

Sub remove(mapTable)
    For Each localname In mapTable
        remotename = mapTable.item(localname)
        WshNet.RemoveNetworkDrive localname, 1, true
    Next
End Sub

kenji さん 2004年 05月 19日 16時 16分 57秒

こんにちわ。ネットワーク・オブジェクトの件でお知恵拝借させて下さい。

次のようなVBスクリプトを書いてクライアントから動的にローカル・ドライ
ブをサーバー上に公開しているデイレクトリーにマップさせ、アプリを起動
して中身を読み、終わればマップを解除するシステムを動かしてます。

デイレクトリーの中身はCD-ROMをそのままコピーしています。CD-ROMはドラ
イブとして扱わないと中身を見せてくれませんから。

'=================================================
'ネットワーク・オブジェクトのインスタンス化
Set WshNet=CreateObject("Wscript.Network")

'接続メソッドの実行
WshNet.MapNetworkDrive "G:", "\\server\dir_1"
WshNet.MapNetworkDrive "H:", "\\server\dir_2"
WshNet.MapNetworkDrive "I:", "\\server\dir_3"

'シェルにアプリを包みこんで起動
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run """C:\XXX.EXE""", 1, true

'アプリが終われば強制的にマップを解除
WshNet.RemoveNetworkDrive "G:",1, true
WshNet.RemoveNetworkDrive "H:",1, true
WshNet.RemoveNetworkDrive "I:",1, true

'=================================================

「同じ処理は一つにまとめる」がプログラムの基本ですから
引数二つを配列に取り込んで渡せないかやってみました。

Set WshNet=CreateObject("Wscript.Network")

dat_1 = array("G:", "H:", "I:")
dat_2 = array("dir_1", "dir_2", "dir_3")

For i = 0 to 2
  WshNet.MapNetworkDrive """dat_1(i)""", """\\server\dat_2(i)"""
Next

デバイス名が間違ってるとエラーを吐きます。

そこで公式

WshNet.MapNetworkDrive "X:", "\\server\Y"

を再現するような文字列を書いて MsgBox で内容を確認しExecute文
に食わせて見ました。

For i = 0 to 2
Execute "WshNet.MapNetworkDrive " & """" & dat_1(i) & """" & ", " & """\\server\" & dat_2(i) & """"
Next

これも駄目でした。

WshNet.MapNetworkDrive のメソッド自体ループは出来ませんか?

まあ元のままでも分かりやすくて出先で中身をメンテする人には優しい
からいいことは良いんですが、不細工なもんで

管理人むたぐち さん 2004年 05月 18日 20時 58分 48秒

ついでに、最近2chに投稿されていたコードを転載しておきます。
Windows Media Playerを使って、mp3やwmaファイルの演奏時間を
取得するスクリプトです。
元はJSでしたが、VBSに直してみました。

Set wmp = CreateObject("WMPlayer.OCX.7")
Set media = wmp.newMedia("C:\Documents and Settings\All Users\Documents\My Music\Sample Music\New Stories (Highway Blues).wma")
MsgBox media.getItemInfo("Duration")

元ネタ: http://pc5.2ch.net/test/read.cgi/win/1058829737/625
リファレンス: http://www.microsoft.com/japan/msdn/library/ja/wmplay/mmp_sdk/windowsmediaplayeractivexcontrol.asp

管理人むたぐち さん 2004年 05月 18日 20時 46分 45秒

To: ばんのしゃーによかばんた さん

> な、なんと、wrapping関数をAddCodeするまでもなく、
> JScriptのグローバルオブジェクトのメソッドを直接に呼べるのですね。

これはお見事としか言いようがないです。
もう、VBSで配列のsortを自前で実装したりしなくてもいいんですね!

ただ一つだけ気になるのは、ScriptControlは標準環境で使用できる
のかってことです。Microsoftの開発環境がなくても大丈夫でしたっけ。

WSHでできることはたいがい洗い出したつもりでいたのですが、
ものすごい勢いで新発見が出てきて楽しいです。

ばんのしゃーによかばんた さん 2004年 05月 18日 18時 44分 42秒

レイアウトを保存したテキストを取り出す方法は、
Generic / Text Onlyプリンタ以外に、

富士通なんたらソフトウェアのシェアウェアのPrintCoordinator、
または、そのOEMでCanonプリンタに付属するPrintCast
に出力し、その出力ファイルからテキスト出力する。

Postscript Printer
に出力し、その出力ファイルをps2txtでテキストに変換する。
ポイントは、
フォントをダウンロードせずにすべてプリンタフォントを使うように設定する。
ポートをファイルにする。
フリーソフトウェアのps2txtを使う。(NiftyのFGALTS)

ところで、
Generic / Text Onlyプリンタは、
英語圏のWin3x/9xユーザには、tty.drvという名前で、常識的な存在のようです。
あちらのプリンタは大抵これで基本的な印刷が出来たようです。
英語圏のひとは大昔から、これを使って簡単にテキストが取れたんですね。

しかし、日本語版Win3x/9xには、とうとう最期まで付いて来なかったですね。
一時Win98βに日本語ヘルプファイルだけが付いていたので、もしかしたら、
と期待が膨らんだのですが、結局は製品版に無かったです。
英語版のままでもよいから、付けておいて欲しかったですね。

以前、MSDNのサンプルコードにソースがあったので、ちょこっと、いじって、
日本語がなんとか出るようにしたtty.drvを作ったのですが、
ライセンス的にどうかなと思って、自分でしか使っていません。
顕著な機能追加をすれば、バイナリを再頒布できるみたいなことが書いてあるので、
ちょこっと、いじったくらいでは駄目かな、と思って。
修正量ではなく、機能的に、日本語が出るのは顕著な機能追加なので、いいかな、
とも思いますが。

ばんのしゃーによかばんた さん 2004年 05月 18日 18時 43分 24秒

>ばんのしゃーによかばんた さん 2004年 05月 17日 17時 29分 43秒
>ScriptControlを使って、
>VBScriptからJScriptのencodeURI/decodeURIを呼び出す例

な、なんと、wrapping関数をAddCodeするまでもなく、
JScriptのグローバルオブジェクトのメソッドを直接に呼べるのですね。

Set SC = CreateObject("ScriptControl")
SC.Language = "JScript"
'Runを使う。
s=SC.Run("encodeURI","http://a.b.c/d e/あ")
WScript.Echo s
WScript.Echo SC.Run("decodeURI",s)
'CodeObjectを使う。
Set js=SC.CodeObject
s=js.encodeURI("http://a.b.c/d e/あ")
WScript.Echo s
WScript.Echo js.decodeURI(s)

でした。

これならJScriptの機能はVBScriptから使い放題ではないでしょうか。

では、逆はどうかと言うと、残念ながら、
JScriptからVBScriptのMsgBoxを直接には呼べないようです。
なぜなんでしょうね。
VBScriptは関数で、JScriptはGlobalオブジェクトのメソッドという違いでしょうか。

また、ExcelのObjectBrowserでjscript.dllを見ると、escapeは見えますが、
encodeURIは見えません。これまた、なぜなんでしょう。
escapeはVersion1でencodeURIはversion5.5という違いでしょうか。
実装が違うんでしょうか。

さて、WSFとHTMLへの応用です。

<job>
<script Language="jscript">
</script>
<script Language="vbscript">
WScript.Echo encodeURI("a b")
</script>
</job>

<html>
<script Language="jscript">
</script>
<script Language="vbscript">
alert encodeURI("a b")
</script>
</html>

な、なんと、こうやっても、
JScriptのグローバルオブジェクトのメソッドを直接に呼べるのですね。
だから、JScriptにしかないものは、わざわざVBScriptに実装する必要はなかった。

メソッドは分かった、オブジェクトはどうか?

VBScriptから、Jscriptの組み込みオブジェクトを使う例。

Set SC = CreateObject("ScriptControl")
SC.Language = "JScript"
'evalを使う。
Set a=SC.eval("new Array()")
a.push("a")
a.push("b")
WScript.Echo a.length
WScript.Echo a
'wrapping関数をAddCodeしてRunを使う。
SC.AddCode("function newArray(){return(new Array());}")
Set a=SC.Run("newArray")
a.push("a")
a.push("b")
WScript.Echo a.length
WScript.Echo a
'RunでなくCodeObjectを使う。
Set js=SC.CodeObject
Set a=js.newArray()
a.push("a")
a.push("b")
WScript.Echo a.length
WScript.Echo a

本当にJScriptの機能はVBScriptから使い放題ですね。
最早、JScriptはVBScriptの一部と言っても過言ではない。

逆が真でないのが、ちょっと引っ掛かりますが。

管理人むたぐち さん 2004年 05月 18日 08時 09分 12秒

http://www.roy.hi-ho.ne.jp/mutaguchi/bbs/list103.shtml
ばんのしゃーによかばんた さん 2004年 04月 25日 16時 24分 29秒
の記事を参考に、「他のフォルダを閉じる」スクリプトを作ってみました。
WinXP用です。2000でも動くかも。

Set WshShell=CreateObject("WScript.Shell")
Set Shell=CreateObject("Shell.Application")
Set dic=CreateObject("Scripting.Dictionary")

For Each window In Shell.Windows
If typename(window.document)="IShellFolderViewDual2" Then
dic.Add window,window.Top
End If
Next

WshShell.SendKeys "%( m)"
WshShell.SendKeys "^{Down}"
WshShell.SendKeys "{Enter}"

For Each window In dic.Keys
If dic.Item(window)<>window.Top Then
WshShell.SendKeys "%( m)"
WshShell.SendKeys "^{Up}"
WshShell.SendKeys "{Enter}"
Else
window.Quit
End If
Next

使い方は、このvbsのショートカットを、お気に入りの「リンク」フォルダに
作成します。これをエクスプローラの「リンク」から実行すると、
他のフォルダウィンドウが閉じます。

工夫した点は、Ctrlを押しながら矢印キーを押すと、ウィンドウは
1ドットしか移動しないことを利用し、できるだけ違和感をなくしたことです。

早いPCだとウェイトを入れなくても特に問題はないようですが、
誤動作するようでしたら、SendKeysの前後にWScript.Sleepを適宜入れて下さい。

"IShellFolderViewDual2"のところを"HTMLDocument"にすれば、IE用も
作れるかもしれません。

これは便利だ…。

ばんのしゃーによかばんた さん 2004年 05月 17日 17時 31分 34秒

-E:VBS -の続報

WScript.StdInとの両立は不可能だと思っていましたが、
コンソールで、

CScript -E:VBS -
WScript.Echo WScript.StdIn.ReadLine
WScript.Echo WScript.StdIn.ReadLine
^Z
aaaaaaaaaaaaaaa (入力)
aaaaaaaaaaaaaaa (出力)
bbbbbbbbbbbbbbb (入力)
bbbbbbbbbbbbbbb (出力)
(終わり)

つまり、
1回目のEOFでスクリプトの終わり。
残りがWScript.StdInになる。

パイプ、リダイレクションでは、
何かスクリプトの終了マーカはないものかと思いましたが、
残念ながら、ないみたい。

しかし、これでは用途がない???

ばんのしゃーによかばんた さん 2004年 05月 17日 17時 30分 34秒

VBSriptを自動で実行した場合、エラーの情報をどうするか。

(A) WScriptで実行する。
ただし、人が居ない所でエラーメッセージが画面に出ても困る。

(B) CScriptで実行して、標準エラーをファイルにリダイレクトしておく。
ただし、エラーコードが出ない。(なぜだ!)

(C) On Error Resume Nextでエラーを拾って、ファイルに書き出す。
ただし、エラー行が分からないので障害調査が困難。

(D) ScriptControlを使う。

元のVBScriptをhoge.vbsとして、

Set fso=CreateObject("Scripting.FileSystemObject")
Set SC = CreateObject("ScriptControl")
SC.Language = "VBScript"
'SC.AllowUI = True
Call SC.AddObject("WScript",WScript,True)
Set file=fso.OpenTextFile("hoge.vbs")
On Error Resume Next
Call SC.AddCode(file.ReadAll())
On Error GoTo 0
file.Close
WScript.Echo "Number",SC.Error.Number
WScript.Echo "Description",SC.Error.Description
WScript.Echo "Source",SC.Error.Source
WScript.Echo "Text",SC.Error.Text
WScript.Echo "Line",SC.Error.Line
WScript.Echo "Column",SC.Error.Column
'適当にファイルかログに書き出す。

※AddObjectの第3引数の意味がヘルプを見ても分かりません。

ばんのしゃーによかばんた さん 2004年 05月 17日 17時 29分 43秒

ScriptControlを使って、
VBScriptからJScriptのencodeURI/decodeURIを呼び出す例

Set SC = CreateObject("ScriptControl")
SC.Language = "JScript"
SC.AddCode("function EncodeURI(s){return(encodeURI(s));}function DecodeURI(s){return(decodeURI(s));}")
'Runを使う。
s=SC.Run("EncodeURI","http://a.b.c/d e/あ")
WScript.Echo s
WScript.Echo SC.Run("DecodeURI",s)
'CodeObjectを使う。
Set js=SC.CodeObject
s=js.EncodeURI("http://a.b.c/d e/あ")
WScript.Echo s
WScript.Echo js.DecodeURI(s)

※AddCodeでファイルの中身をReadAllして渡せば、#include擬になります。
インクルードファイルごとにModuleを分けることも出来ます。

ScriptControlを使った配列のSortの例

配列そのもののソート

arr=Array("お","あ","え","い","う")
Set SC = CreateObject("ScriptControl")
SC.Language = "JScript"
SC.AddCode("function VBArraySort(vbarray){" & _
"return(new VBArray(vbarray).toArray().sort());}")
Set js=SC.Run("VBArraySort",arr)
WScript.Echo js 'あ,い,う,え,お
WScript.Echo TypeName(js) 'JScriptTypeInfo
WScript.Echo js.length '5
For Each item In js
WScript.Echo item
Next

例えば、ファイルを更新日付順にソートするように、
主キーと別にソートキーがある場合はインデクスのArrayを返す。

FSOのFilesのようにインデクスでアクセス出来ないものは、主キーの配列を
予め作っておく。

Set fso=CreateObject("Scripting.FileSystemObject")
Set Folder=fso.GetFolder(".")
ReDim keys(Folder.Files.Count-1)
ReDim vals(Folder.Files.Count-1)
k=0
For Each File In Folder.Files
keys(k)=File.Name '主キー
vals(k)=File.DateLastModified 'ソートキー
k=k+1
Next
Set SC = CreateObject("ScriptControl")
SC.Language = "JScript"
SC.AddCode "function VBArraySort(vbarray){var a=new VBArray(vbarray);" & _
"var b=new Array();for(var c=0;c<=a.ubound();c++) b[c]=c;" & _
"return(b.sort(compare));function compare(x,y){var ax=a.getItem(x);" & _
"var ay=a.getItem(y);if(ax>ay)return(1);if(ax<ay)return(-1);return(0);}}"
Set js=SC.Run("VBArraySort",vals)
'WScript.Echo js
'WScript.Echo TypeName(js)
WScript.Echo js.length
For Each item In js
WScript.Echo item,keys(item),Folder.Files(CStr(keys(item))).DateLastModified
Next

※Fileオブジェクトを配列にして、比較関数でDateLastModifiedを比較することも
出来ますが、汎用性が低下します。

ばんのしゃーによかばんた さん 2004年 05月 17日 17時 28分 41秒

VBScriptのエラーのコードとメッセージは以下で取り出せます。
ヘルプにもありますが、ヘルプを立ち上げて、辿り着く手間や、
HTMLで保存して、IEの立ち上がる時間が鬱陶しい向きには、
テキストで見るのが手っとり早いでしょう。

On Error Resume Next
For n=1 To 2000
Err.Clear
Err.Raise n
If Err.Description<>"未知の実行時エラーです。" Then
WScript.Echo Hex(Err.Number),Err.Number,Err.Description
End If
Next

VBScript以外のエラーは、難しいですね。

DLLからStrings/uでUnicode文字列をダンプすれば、メッセージだけはなんとか
分かりますが、番号までは分からない。

メッセージも、もっと華麗にWin32APIかRES://〜.DLL/〜で取り出せないないもの
でしょうか。

ところで、
ヘルプの場合、検索やキーワードでページが移ると、
目次もその部分が開いて移りますが、
MSDNの場合、検索してページを開いても、
目次からそのページへの辿り方が分かりません。
何かコツがあるのでしょうか。

ばんのしゃーによかばんた さん 2004年 05月 16日 21時 42分 12秒

MSHTML.DLLを見ていたら、Generic / Text Onlyという文字列がありました。
それで思い出した。

みなさーん、Generic / Text Onlyプリンタを使ってますか?
折角Windowsに標準で入っているのに使わないのは勿体ない。
どんどんがばちょと使いましょ。

テキストを取り出すとき、すべて選択+コピー、ではレイアウトが失われます。

WindowsNT/2000/XPでは、
汎用的にレイアウト付きでテキストを取り出す方法として、
Generic / Text Onlyプリンタが使えます。

プリンタの追加
ローカルプリンタ
ポート FILE:
製造元 Generic
プリンタ名 Generic / Text Only
で登録します。

IEなどで印刷すれば、レイアウトを保ったテキストが得られます。
ただ、改行がLFのみなので、そのままNotePadで開くと改行が潰れます。
ここはVBScript/JScriptでCR+LFに変換しましょう。

ポート FILE:のままでは、毎回FILE:を聞いて来ます。
もし、それが面倒なら、デスクトップなどの固定のファイル名を指定します。
プリンタのプロパティで、
ポート(または詳細)
ポートの追加
その他
ローカルポート
C:\DOCUME~1\ADMINE~1\デスクトップ\textonly.txt
などを追加し、
印刷先のポート
で選択します。

ばんのしゃーによかばんた さん 2004年 05月 16日 21時 41分 07秒

>ねやがわ さん 2004年 05月 12日 20時 11分 25秒
>FSO.WSFのファイルを作成し実行したところ、
>"ForAppending"等の値が表示できていました。
>参照設定について調べてみましたが、
>VBScriptだけで"ForAppending"等の値を引っ張って来ることが分かりません。

どういう環境(Win,IE,(WSH,VBScript))をご使用なのか、分かりませんが、
Vbscrip5.chmやScript56.chmなどはありませんか?

まず、これらヘルプを参照されることを強くお勧めします。

例えば、Vbscrip5.chmのキーワードでForAppendingを見ると、

ファイル入出力の定数 1/1 ページ

Microsoft7 Visual Basic7 Scripting スクリプティング ランタイム リファレン
Edition ス
ファイル入出力の定数 バージョン 2


関連項目

コード内で定数を使用するには、目的の定数の定義が入った適切なタイプ ライブラリをプロジェクトから明
示的に参照しておく必要があります。VBScript の場合、これらの定数はコード内で明示的に宣言してく
ださい。

定数 値 内容
ForReading 1 読み取り専用でファイルを開きます。
ForWriting 2 書き込み専用でファイルを開きます。同じ名前のファイルが存
在する場合は、上書き保存されます。
ForAppending 8 ファイルの末尾から追加書き込みをするためのファイルを開き
ます。

---
と、しっかり書かれています。

Script56.chmの場合には、キーワードになく、検索で探すと、内容は異なりますが、
サンプルコードを見ると、自分で宣言していることが分かります。

インターネットで探すよりローカルのヘルプファイルで探すほうが簡単です。

ところで、
みなさ〜ん、上のヘルプをテキストにしたものはどうやったか分かりますか?
すべて選択、コピー、NotePadに貼り付け、や
ソースを表示、HTMLで保存して、IEで表示、テキストで保存、だと
レイアウトが崩れてしまいます。それで他の方法を使いました。

いりや さん 2004年 05月 16日 17時 14分 02秒

Ryo さん、

わたしもこちらのフォーラムに参加されている皆さんとお話するのを楽しみに
しています。

ジョン・ベントリーさんがプログラミングを仕事にすることをすすめる理由とし
てこんなことをおっしゃっていました。

「(前略)人間にあった入出力を作る過程で素晴らしい経験ができる。それは、
作成中にたくさんの魅力的な人と会って話をする機会に恵まれるということだ」
[1] Page.101

社会人になり九年目になりますが本当に感じています。

いりや

[1] プログラマのうちあけ話―続・プログラム設計の着想
http://www.amazon.co.jp/exec/obidos/ASIN/4764901773/250-6011853-7688223

黒騎士F91 さん 2004年 05月 15日 01時 05分 39秒

ばんのしゃーによかばんた さんアドバイスありがとうございます。
文字コードを変えるソースをありがとうございます。活用させていただきます。
> >WSHShell.Run "test.txt へのショートカット.lnk"
> では、このエラーにならないはず。
いや、ソースのままでエラーになるのです。が、書きながら自信がなくなってきました。XPで同じエラーが再現できました。
エラー内容からするとばんのしゃーによかばんた さんの言うとおりに思えてきました。
月曜になりますが、Win98で実験してみます。
ありがとうございました。


ばんのしゃーによかばんた さん 2004年 05月 15日 00時 00分 52秒

>黒騎士F91 さん 2004年 05月 13日 21時 28分 07秒
>Win98、IE6で実行するとなぜかErr.Numer=-2147352567、メッセージ文字化け?がでます。
>実行はできているので、On Error Resume NextとErr.Clearで回避しているのですが、えらーが出ることの原因がわかりません。
>WSHShell.Run "test.txt へのショートカット.lnk"

文字化けの原因は、誰か(?)がUnicodeをShiftJISだと思って、
ShiftJIS->Unicode変換するからです。誰だ!?
そこで、以下のようにUnicode->ShiftJIS逆変換してやると、
一旦ShiftJIS->Unicode変換で「?」に化けたもの以外は復号できます。

Set wShell=CreateObject("WScript.Shell")
On Error Resume Next
rc=wShell.Run("..\text.lnk",0,True)
ErrNumber=Err.Number
ErrDescription=Err.Description
On Error GoTo 0
For k=1 To Len(ErrDescription)
x=Asc(Mid(ErrDescription,k,1))
If x<0 Then x=x+256*256
If x>255 Then
Description=Description & ChrB(x \ 256) & ChrB(x Mod 256)
Else
Description=Description & ChrB(x)
End If
Next
WScript.Echo rc,Hex(ErrNumber),Description

Hex(-2147352567)=80020009
処理を待つことができません。
が化けて、
処理??つことができませ?。
英文は
Unable to wait for process.

しかし、
>WSHShell.Run "test.txt へのショートカット.lnk"
では、このエラーにならないはず。

WSHShell.Run "test.txt へのショートカット.lnk",,True
としていたのではないでしょうか。

WSHShell.Run "test.txt へのショートカット.lnk",,True

処理を待つことができません。
のエラーになるのはそういう仕様なのでは?

Ryo さん 2004年 05月 14日 22時 12分 35秒

いりやさん、

ご親切なアドバイスありがとうございました。innerTextだけでも取れましたが
DHTML風にするともっと正確に辿れるんですね。

ただしさんとの遣り取り拝見いたしました。技術論に留まらずお二人とも人間臭
い部分を本音で語られているを知り社会人として心構えと言うかチームワークに
対する考え方を教えて頂き実にありがとうござました。

このフォーラムは道理をわきまえられた爽やかな方が多いのでとても楽しみにし
ています。

未熟な者ですが今後とも何卒よろしくお願い致します。

いりや さん 2004年 05月 14日 15時 59分 25秒

Ryo さん、

| Stream.Write objIE.document.body.innerText 'テキスト形式で書き込み

こちらですが、フレーム構造をしていない画面なのであれば、

Nakami = objIE.document.parentWindow.document.body.parentElement.outerHTML

を試してみてください。たぶん・・・とれるんじゃないかと。

それから、

| あるURLのページをダウンロードして正規表現を使い中身から特定の文字列
| を抜き出すスクリプトを書きました。

こちら、以前同様な課題に取り組まれた方がいらっしゃいました。

http://www.roy.hi-ho.ne.jp/mutaguchi/bbs/list100.shtml

100-49 いりや さん     2004/03/04 02:08
100-48 ただし さん     2004/03/03 21:22
100-35 いりや さん     2004/02/29 20:18
100-34 ただし さん     2004/02/29 18:37
100-33 管理人むたぐち さん 2004/02/29 16:05
100-32 いりや さん     2004/02/29 15:36
100-30 いりや さん     2004/02/29 15:11
100-29 ただし さん     2004/02/29 12:38

ご参考までにどうぞ。

ふみふみ さん 2004年 05月 14日 15時 18分 29秒

管理人むたぐち さん、こんにちは。
お返事が大変遅くなりました。申し訳ございません。
現在も「履歴」と格闘中です。(笑)

> > URL のエンコードとデコードの問題の模様にも思えるのですが…。
>
> なんとなく、UTF-8の扱いでこけている感じもします。
> とりあえず手作業で修正が効くのであれば良いですね。
> よければ、ちょっとコードを教えてもらえませんでしょうか。

手作業での修正というのは、回避するためのコードを書いて対策している
のではなくて、9x系のOS では
Set objFolder=Folder.NameSpace("C:\WINDOWS\History")
として、書き出された HTML の中に含まれる検索エンジンの URLの部分を
履歴フォルダのものにひとつずつ修正しています。
場合によっては、非常に手間と時間がかかります。(笑)

NT5.x系のOS の場合、履歴に URLエンコードされているコンテンツがある
場合(だと思うのですが)、
Set objFolder=Folder.NameSpace("shell:History")
だと Error となるので、Error を起こしそうなものを予め c:\workにcopy
をしておいて、
Set objFolder=Folder.NameSpace("C:\work")
として書き出し、該当するものを履歴フォルダから削除した後に
Set objFolder=Folder.NameSpace("shell:History")
を書き出し、双方のマージを行っています。
9x系のOS の場合よりも、さらに時間と手間がかかります。(涙)

UTF-8 や Unicode の問題となると OSにも依存する問題のようで、どうして
良いものなのやら…。

参考にならないお返事ばかり差し上げて申し訳ありません。

Ryo さん 2004年 05月 14日 13時 02分 04秒

魔界の仮面弁士さん、さっそくのお返事ありがとうございました。

どちらの方法も上手く行きました。カーソル位置の変更で出来るんですね。
大変勉強になりました。

XMLHTTP(書き間違いで失礼)オブジェクトの代わりに好きじゃないんです
がIEを裏で動かしてファイルをダウンロードする同様のスクリプトも書い
てます。該当部分は

'IEアプリ・オブジェクトのインスタンス化
Set objIE = WScript.CreateObject("InternetExplorer.Application")

objIE.Visible = False '不可視にする
objIE.Navigate(URL変数) '指定のURLでIEを起動

Do While objIE.Busy 'ループで読み取り
Loop
Do While objIE.Document.readyState<>"complete"
Loop

'ファイル・オブジェクトのインスタンス化
Set fs = WScript.CreateObject("Scripting.FileSystemObject")
Set stream = fs.CreateTextFile(ファイル変数) '器のファイルを指定
Stream.Write objIE.document.body.innerText 'テキスト形式で書き込み
Stream.Close


ObjIEをADOのStreamに渡せるかとおもって試して見たのですが駄目でした。
そんなことする必要もないか。

重ねて御礼申し上げます。

はじめ さん 2004年 05月 14日 13時 00分 51秒

VBSの暗号化について私の経験をご紹介しておきます。

> 3の場合は、MSScript Encoderを使う事ができます。

使えることは使えますが下記のツールで簡単に解読出来ます。

http://www.klaphek.nl/nr6/scrdec.html

私は95/98の頃はVBSに似たDLLの拡張言語でWinBatchを使ってました。

http://www.agtech.co.jp/products/winbatch

構文はVBに良く似てます。これだとコンパイラー付きもありますから
バイナリーにすればソースは分かりません。100ドル出してアメリカか
ら取り寄せたことがありましたが今どれ位するのかな。

今はVBというかASP専念だから使ってません。評価版もありますよ。

ご参考まで

魔界の仮面弁士 さん 2004年 05月 14日 12時 20分 05秒

> 自レスですが
あら、すでに解決してたんですね…。(^^;

魔界の仮面弁士 さん 2004年 05月 14日 12時 18分 35秒

》 しー さん

1. コードが第3者に改竄されるのを防ぎたい。
2. 第3者に実行されないよう、復号しないと実行できないようにしたい。
3. ソースを見られたくないが、暗号化したまま実行できて欲しい。

2の場合、パスワード付きzipにしておくという方法があります。
あるいは、CAPICOMを使うのも手でしょう。
(パスワードを知らなければ、ソースは見えません)

1の場合は、VBScriptに電子署名を付けるのが良いでしょう。
ただし、ソースそのものは丸見えです。2と併用すると良いかも。
実際に署名するには、.NETなどにも付属しているSigncode.exeツールを使う方法と、Script.Signerオブジェクトを使う方法とがあります。
http://www.microsoft.com/japan/msdn/columns/scripting/scripting11132000.asp

3の場合は、MSScript Encoderを使う事ができます。
http://www.asia.microsoft.com/japan/msdn/library/ja/script56/html/SeconScriptEncoderOverview.asp
http://www.microsoft.com/downloads/details.aspx?FamilyID=2976ee94-bec5-4314-84fd-8d7ec891c1c5&DisplayLang=ja
この場合の言語指定は
<script language="VBScript"> ではなく、<script language="VBScript.Encode">となります。

# ASPの場合は、<%@ LANGUAGE="VBScript.Encode" %>

しー さん 2004年 05月 14日 12時 10分 29秒

自レスですが
スクリプトエンコーダですね。
お騒がせしました。

しー さん 2004年 05月 14日 11時 33分 45秒

VBSでWSHを作成しているのですが、
.vbsファイルを暗号化してソースを見えなくする
方法ってないかでしょうか?
昔どこかで見たような記憶があるのですが、(MSのサイトかも)
知っている方がいらっしゃいましたら教えてください。

魔界の仮面弁士 さん 2004年 05月 14日 11時 07分 18秒

> VBSのStreamオブジェクトについてお尋ねします。
「ADOのStreamオブジェクト」をVBScriptから利用している、という事ですね。

> Set 接続変数 = Wscript.CreateObject("Microsoft.XHTTML")
"Microsoft.XHTTML" → "Microsoft.XMLHTTP" なのでは。

> 上手く動いてくれますが、一度ファイルに落としたものを加工しています。
> ファイルに落とさず加工する方法はないでしょうか?

サーバの設定によっては、単純に
strData = objXMLHTTP.responseText
だけで済むこともあるので、一度試してみてください。

それでは駄目なようであれば、以下のようにしてみてください。

Const adTypeBinary = 1
Const adTypeText = 2
Set Stm = WScript.CreateObject("ADODB.Stream")
Stm.Open
Stm.Type = adTypeBinary
Stm.Write objXMLHTTP.responseBody

Stm.Position = 0
Stm.Type = adTypeText
Stm.Charset = "Shift_JIS" 'Webサーバの文字コードを指定してください。

strData = Stm.ReadText()

Stm.Close
Set Stm = Nothing


カーソル位置を先頭にする(つまり、Positionプロパティを0にする)事で、テキストモードとバイナリモードを変更したり、あるいは文字コードの変更を行う事ができるようになります。

Ryo さん 2004年 05月 14日 10時 21分 07秒

VBSのStreamオブジェクトについてお尋ねします。

あるURLのページをダウンロードして正規表現を使い中身から特定の文字列
を抜き出すスクリプトを書きました。

上手く動いてくれますが、一度ファイルに落としたものを加工しています。
ファイルに落とさず加工する方法はないでしょうか?

具体的には、

Set 接続変数 = Wscript.CreateObject("Microsoft.XHTTML")

で接続のオブジェクトを作り、対象を取ってきて

Set Stream = WScript.CreateObject("ADODB.Stream")

ADODBで器のStream オブジェクトを作り、

Stream.Write 接続変数.responseBody
Stream.Savetofile セーブ先ファイルパス、adSaveCrateOverWrite

でファイルに上書きさせ、

ファイル・オブジェクトを作りOpenTextFileメソッドでそのファイルを開い
て中身を Readallで読み取り別の変数に代入しています。

ファイルに落とす所を手抜き出来ないのかStreamオブジェクトを調べて見た
らHTMLの場合binary扱いとなりますから

Nakami = Stream.Read

で別の変数に代入出来ますが、これをそのまま正規表現オブジェクトを作っ
て渡すと”型が違います”とけられます。

Streamの中身をそのまま加工できませんか?

全然的外れだったらごめんなさい。

黒騎士F91 さん 2004年 05月 13日 21時 28分 07秒

ちわ♪黒騎士です。
毎度お世話になります。

下記のようなショートカットを実行するVBSなのですが、
XP、IE6で実行したところエラーは出ません。
Win98、IE6で実行するとなぜかErr.Numer=-2147352567、メッセージ文字化け?がでます。
実行はできているので、On Error Resume NextとErr.Clearで回避しているのですが、えらーが出ることの原因がわかりません。
Win98では2台で実験して環境依存ではないだろうと推測しています。
原因がわかる方がおられたら教えてください。
ーーーーー
On Error Resume Next
Dim WSHShell
Set WSHShell = WScript.CreateObject("WScript.Shell")
WSHShell.Run "test.txt へのショートカット.lnk"
MsgBox Err.Number
ーーーーー

ねやがわ さん 2004年 05月 13日 20時 46分 30秒

>>魔界の仮面弁士さん

今回は自前で定義しようと思います。
もっと勉強しないといけないですね。
色々とありがとうございました。

ばんのしゃーによかばんた さん 2004年 05月 13日 18時 15分 05秒

>ばんのしゃーによかばんた さん 2004年 05月 08日 20時 11分 49秒
>>さらに、98/MEでは、
>>Command.comやbatファイルや16ビットコンソールアプリをExecすると、
>>CScriptでは動いても、WScriptではhang upします。:-<
>>32ビットコンソールアプリはOK。
>hang upはoExec.StdOut/StdErrのEOFが上がらないためのようです。
>EOFなのに更に読もうとして永久待ちになるようです。
>command.comがstdout/stderrをdupしたまま、ほったらかしているのかも。
>回避方法はどうもなさそう。

回避方法がありました。

98/MEでは、Command/cの代わりに、Perlに同梱のCMD32.EXEを使うことです。

Set oExec=wShell.Exec("C:\Perl\Bin\Cmd32.Exe コマンド")

97年のdocs\Perl-Win32\WIN95.TXTに記述があるくらいですから、
思いっきり既知の問題だったようです。
なんか、16ビットCommand.comがWin32のパイプを知らないせいみたい。

これにより、

>ばんのしゃーによかばんた さん 2004年 05月 06日 19時 32分 07秒
>>管理人むたぐち さん 2003年 07月 01日 20時 39分 10秒
>>To: 神 さん
>>> ワイルドカードを含む任意のファイル名から、実在するファイル名を取得したいのですが
>>VBSやFileSystemObjectにはワイルドカードを展開する機能はありません。
>>ので、そういうコードを書いてやる必要があります。
>>ワイルドカードを含む文字列を与えると、マッチしたFileオブジェクトあるいは
>>Folderオブジェクトの格納された1次元配列を返すような関数にすれば
>>使い勝手が良さそうです。
>2000/XPはCScript/WScript共に可、
>98/MEはCScript限定、
>ですが、
>Set wShell=CreateObject("WScript.Shell")
>Set oExec=wShell.Exec("%comspec% /c dir /b *.*")
>'WScript.Echo oExec.StdOut.ReadAll()
>a=Split(oExec.StdOut.ReadAll(),vbCRLF)
>WScript.Echo UBound(a),Join(a,";")

98/MEで、CScript/WScript共に、

Set wShell=CreateObject("WScript.Shell")
Set oExec=wShell.Exec("C:\Perl\Bin\Cmd32.exe dir /b *.*")
'WScript.Echo oExec.StdOut.ReadAll()
a=Split(oExec.StdOut.ReadAll(),vbCRLF)
WScript.Echo UBound(a),Join(a,";")

さらに、Perlに同梱のPerlGlob.Exeを使うことも出来ます。

Set wShell=CreateObject("WScript.Shell")
Set oExec=wShell.Exec("C:\Perl\Bin\PerlGlob.exe *.*")
'WScript.Echo oExec.StdOut.ReadAll()
a=Split(oExec.StdOut.ReadAll(),vbNullChar)
WScript.Echo UBound(a),Join(a,";")

違いは出力がvbNullChar=Chr(0)で区切られていること。

ばんのしゃーによかばんた さん 2004年 05月 13日 18時 14分 10秒

>ばんのしゃーによかばんた さん 2004年 05月 12日 19時 51分 22秒
>あのヘルプで分かるひとは凄いです。私は分からなかったので、テストで確認しました。
>ExecuteGlobal file.ReadAll()
>を
>Execute file.ReadAll()
>に変えると、
>cとsss()が見えなくなります。
>これらはSub Include()の中でだけ見えます。
>結局、そういうことをあのヘルプを言っているらしい。

てにをは、訂正。
結局、そういうことをあのヘルプ は 言っているらしい。
でした。

ついでに、
Cなどでは、関数定義をネストできるのですが、
VBScriptでは、
Sub aaa()
Sub bbb()
End Sub
Sub ccc()
End Sub
Call bbb()
Call ccc()
End Sub
は出来ません。:-<

ところが、executeを使うと、こんなこと、
Sub aaa()
Execute "Sub bbb()" & vbCRLF &
"End Sub" & vbCRLF &
"Sub ccc()" & vbCRLF &
"End Sub" & vbCRLF
Call bbb()
Call ccc()
End Sub
が出来るらしい。どういう価値があるかは分かりません。。。

魔界の仮面弁士 さん 2004年 05月 13日 16時 45分 22秒

》 ねやがわ さん
> 教えていただいた方法はホームページの作成に関係する物ですね?。

関係する物もありますし、関係しない物もあります。

「Windows Scripting Host(WSH)」は、Webページとはあまり関係が無いです。
WSHには、バッチファイルのようにコンソールで実行(CScript.exeによる実行)
されるものと、ウィンドウベースの物(Wscript.exeによる実行)の、2つのモードが
ありますが、そのいずれもがローカルで実行される物であり、Webアプリとは
直接関係はありません。
http://www.int21.co.jp/pcdn/vb/noriolib/vbmag/9910/wsh/


一方、「Active Server Pages(ASP)」は、Webページの作成に関係があります。
この場合のVBScriptは、Webサーバ上で実行されます。
(ファイル名は global.asa や *.asp など)


「Windows Script Components」は、どちらとも言えます。(*.wscファイル)
ASPからでも、IEからでも、WSHからでも使うこともできるからです。
http://www.microsoft.com/japan/msdn/columns/scripting/scripting091399.asp


なお、「HTML Application」(*.hta)は、HTMLの文法で画面を作成する物ですが、
それ自体はWebアプリではありません。(ローカルで実行される物です)
そしてHTAには、タイプライブラリを読み込む機能は無いみたいです(私が知らないだけかも)

他のスクリプト実行環境としては、「HTML Components」という物もあります。(*.htc)
これはIE上で実行される物なので、Webの作成に関係があります(DHTML関連)。
こちらもHTML Application同様、タイプライブラリを読み込む機能が無いようです。

ねやがわ さん 2004年 05月 13日 14時 03分 35秒

>>魔界の仮面弁士さん

詳しく説明していただきありがとうございます。
今作っているのはMS-DOSのバッチファイルの様な物です。
当方の知識不足と言葉足らずで申し訳ないのですが、
教えていただいた方法はホームページの作成に関係する物ですね?。
これだけ説明して頂いたのに答えが見えてこない自分がもどかしいです。

魔界の仮面弁士 さん 2004年 05月 13日 10時 34分 49秒

》 ねやがわ さん
> VBScriptだけで"ForAppending"等の値を引っ張って来ることが分かりません。

ActiveX DLL中で定義された列挙値や定数値を利用するには、
タイプライブラリ情報を「参照設定」する必要があるのですが、
単体の*.VBSファイル自身には、参照設定する機能がありません。

参照設定を行うには、以下のような手法があります。

・Active Server Pagesの場合: ASPまたはglobal.asaにて、METADATA宣言を行う。
<!--METADATA TYPE="TypeLib" NAME="Microsoft Scripting Runtime"
UUID="{420B2830-E718-11CF-893D-00A0C9054228}" -->

・Windows Scripting Host (2.0以上)の場合: WSFファイルのreference要素で指定する。
→先述のサンプルを参考に。

・Windows Script Components の場合: WSCファイルのreference要素で指定する。
→WSFと同様。<reference>要素を作り、object="Scripting.FileSystemObject" か、
 もしくは guid="{420B2830-E718-11CF-893D-00A0C9054228}" という属性値を記述。

・HTML Application(*.hta)の場合:
→わかりません。(泣)


参照設定が使えない場合は、Const定義を自分で書かなければいけません。

# ADOの場合は、adovbs.incをインクルードするだけで済みますが、
# FSOの場合は、インクルードファイルが用意されていないようで…。

ねやがわ さん 2004年 05月 12日 20時 11分 25秒

>>魔界の仮面弁士さん
早速の回答ありがとございます。
FSO.WSFのファイルを作成し実行したところ、
"ForAppending"等の値が表示できていました。
参照設定について調べてみましたが、
VBScriptだけで"ForAppending"等の値を引っ張って来ることが分かりません。
宜しくお願いします。

ばんのしゃーによかばんた さん 2004年 05月 12日 19時 51分 22秒

>管理人むたぐち さん 2004年 05月 12日 18時 15分 31秒
>> ExecuteGlobal file.ReadAll()
>私が先ほど書いた3つ目の方法はこれですね。
>ExecuteとExecuteGlobalの違いって何でしたっけ。
>ヘルプに何やら説明してありますが、なんか分かったような
>分からないような。

あのヘルプで分かるひとは凄いです。私は分からなかったので、テストで確認しました。

ExecuteGlobal file.ReadAll()

Execute file.ReadAll()
に変えると、
cとsss()が見えなくなります。
これらはSub Include()の中でだけ見えます。
結局、そういうことをあのヘルプを言っているらしい。

executeを使うなら、Sub include()を使わない、こういうやり方もあります。
一行にてんこ盛り。

incfile="a.inc"
Execute CreateObject("Scripting.FileSystemObject").OpenTextFile(Left(WScript.ScriptFullName,Len(WScript.ScriptFullName)-Len(WScript.ScriptName)) & incfile).ReadAll()

WScript.Echo b
WScript.Echo c
call sss()

>エージェントをここまで自由に操れるなら、積極的に使いたくも
>なってきますね。
>MsgBoxの「はい」「いいえ」の代替とかもできるんでしたっけ。

マウスのボタンの左右とかダブルクリックはEventで取れるようですが、
ボタンを表示することは出来ないようです。
Office Assistantなら出来るのですが。

ところで、このヘルプも使いにくい。
オブジェクトプラウザで調べてヘルプを検索しないと見つからない。

ばんのしゃーによかばんた さん 2004年 05月 12日 19時 10分 55秒

>管理人むたぐち さん 2003年 08月 13日 17時 35分 03秒
>VB.NETなら、ショートサーキット評価をする論理積はAndAlsoなので、
>moWindow.busy AndAlso moWindow.readyState <> 4
>になりますね。
>ショートサーキット評価をする論理和ならOrElseです。
>VB/VBSにショートサーキット評価をする論理演算子はありません。
>And(論理積)とOr(論理和)のみです。

そこをなんとか。

If A AndAlso B Then
C
End If

だけは、

If A Then
If B Then
C
End If
End If

と書けますが、それ以外の

If A AndAlso B Then
C
Else
D
End If



If A OrElse B Then
C
Else
D
End If

はどうしたものか。

If A Then
If B Then
C
Else
D
End If
Else
D
End If



If A Then
C
ElseIf B Then
C
Else
D
End If

では、二重コーディングが嫌です。

AndAlsoは、
Do
If A Then
If B Then
C
Exit Do
End If
End If
D
Exit Do
Loop

OrElseは、
Do
If A Then
ElseIf B Then
Else
D
Exit Do
End If
C
Exit Do
Loop

美しくないので、どうしても必要なときだけにしましょう。
下手すると本当にLoopするので、安全のため、Loop While 0のほうがよいかも。

因みに、

>VB/VBSにショートサーキット評価をする論理演算子はありません。
>And(論理積)とOr(論理和)のみです。

そもそも、AndとOrなどは論理演算子だ、と思わないで、ビット演算子だ、
と思っておいたほうが安全で間違いがないのではないでしょうか。
そう思えば、If A And B Thenの振る舞いも容易に理解できます。

管理人むたぐち さん 2004年 05月 12日 18時 15分 31秒

前ページの返信から。

To: ばんのしゃーによかばんた さん

> IAgentCtlRequest.Statusが、2(pending)->4(progress)->0(completed)と変化するので、
> 話し終わるのは0になるのを待てばよいようです。

おお、結構使えるかもしれないですね。
話し終わるのを待って次の処理を実行させるのは、時間の無駄なんで、
「話し終わる前に処理が終了していた場合は、話を中断させて、
次のメッセージを強制的に出す」
とかの処理を組み込んで行くといい感じだと思います。
(Balloon.Visible=Falseで中断できるのかな?)

エージェントをここまで自由に操れるなら、積極的に使いたくも
なってきますね。
MsgBoxの「はい」「いいえ」の代替とかもできるんでしたっけ。
あとは、もうちょっと日本人の趣味にあった絵が欲しいですな。
カイル君も冴子先生もいいのだが、やはり偽春菜みたいな…ってまたそれか。


To: ふみふみ さん

> URL のエンコードとデコードの問題の模様にも思えるのですが…。

なんとなく、UTF-8の扱いでこけている感じもします。
とりあえず手作業で修正が効くのであれば良いですね。
よければ、ちょっとコードを教えてもらえませんでしょうか。


To: ばんのしゃーによかばんた さん

> ExecuteGlobal file.ReadAll()

私が先ほど書いた3つ目の方法はこれですね。
ExecuteとExecuteGlobalの違いって何でしたっけ。
ヘルプに何やら説明してありますが、なんか分かったような
分からないような。

> ところで、
> cscript.exeの中に
> WScript_OnScriptTerminate
> という文字列が見えます。

怪しいですね。
でも、オブジェクトブラウザでは見られないですし、
ただ、「WScript_OnScriptTerminateってのがあったら便利かも、
そのうち実装しちゃうかも?」という開発者のコメントの
断片なだけかもしれません。

管理人むたぐち さん 2004年 05月 12日 17時 33分 05秒

ファイル共有ソフト、Winnyの作者が、「著作権法違反幇助」の容疑で
逮捕されたという話は、みなさんもご存知だと思います。

また、それと時を同じくして、Winnyの使い方などを紹介していた
サイトの管理人が、家宅捜索を受けたとのことです。

しかし、「幇助」という言葉は便利ですね。
ウイルス(ワーム)作りを容易にせしめた、WSHという技術を作った
マイクロソフトは、ウイルス作成罪(まだないですが)幇助になるという理屈ですね。
そして、その技術を紹介したこのサイトの管理人は、当局により家宅捜索を
受けるのですね。

これが一般のプログラミング解説サイトなら、たぶんあまり問題には
ならないとも思うのですが、一時期は猛威を振るったワームに
悪用もされた技術の解説というのは、目をつけられるんじゃないかと
わりと本気で心配しています。
他にも、ActiveX、DCOM、HTA等々、昨今のウィルス/ワームで使われる技術を
色々と取り上げていますしね。

もちろん私はこれまでに、ワームの類はもちろんのこと、悪用すると犯罪行為に
繋がるコードは一つも公開していませんが、ほんの数行の改変により、
そういったコードになる可能性までは、はっきり言って責任が持てません。

そんなの杞憂にすぎないでしょう、と思われるかもしれませんし、私だって
Winny紹介サイトの管理人が家宅捜索を受けたという話を聞くまでは
そう思ってましたが、どうもこれは杞憂だと言って流せる問題では
なくなっているようです。

WinnyもWSHも、平和利用も悪用もできるツールです。Winnyの方が、
悪用されている率が、WSHよりほんの少し高いと想像できる程度の差しか
ありません。WSHは悪者と断じて、アンインストールを薦めるサイトや
書籍(やノートン先生w)が多数あることを鑑みても、
かなり旗色が悪いのではないでしょうか。

と言っても、今日明日にサイトを閉める気はありませんので、
利用者の皆様におかれましては、とりあえず安心していただきたい
と思います。今後の情勢に要注目と言ったところでしょうか。

魔界の仮面弁士 さん 2004年 05月 12日 16時 07分 50秒

》ねやがわ さん
> 手持ちの本ではOpenTextFileのパラメータに"ForAppending"などの
OpenTextFileは、VBScritのメソッドではありません。
FileSystemObjectという、外部コンポーネントのメソッドです。

そのため、VBScript に ForAppending という定数を知らせるために、
FileSystemObjectを提供している SCRRUN.DLL を「参照設定」するか、
もしくは、自前でConst定義を行う必要があります。


========= C:\FSO.WSF =========
<?xml version="1.0" encoding="Shift_JIS"?><job>
<reference object="Scripting.FileSystemObject" />
<object id="FSO" progid="Scripting.FileSystemObject"></object>
<script language="VBScript"><![CDATA[

'「参照設定」が正しく行われているかの確認。
MsgBox TypeName(FSO) & vbCrLf _
& "ForAppending=" & CStr(ForAppending) & vbCrLf _
& "ForReading=" & CStr(ForReading) & vbCrLf _
& "ForWriting=" & CStr(ForWriting), vbInformation

Dim Txt
Set Txt = FSO.OpenTextFile("C:\testfile.txt", ForWriting, True, TristateFalse)
Txt.Write "魔界の仮面弁士"
Txt.Close
Set Txt = Nothing

MsgBox "正常に出力されました。", vbInformation, "C:\testfile.txt"

]]></script></job>

ねやがわ さん 2004年 05月 12日 15時 40分 40秒

はじめまして。
VBScriptにてファイルのオープンをしようとしています。
手持ちの本ではOpenTextFileのパラメータに"ForAppending"などの
定数が使われています。
しかしこのまま"ForAppending"を使用するとエラーがでてしまいます。
インターネットで調べてみると"ForAppending = 8" といった様に
スクリプト中で記述しているのはありました。
"ForAppending"等の値はどこかに用意されていないのでしょうか?。
宜しくお願いします。

魔界の仮面弁士 さん 2004年 05月 12日 12時 07分 22秒

》 猫足 さん
> objXL.Workbooks.OpenText("xxxxxx.txt",,,xlDelimited,xlTextQualiferNone,,,,Comma,,,,Array(Array(2,2))

「xlTextQualiferNone」ではなく、
「xlTextQualifierNone」ですよね。


> 「OpenTextメッソドが失敗しました」とエラーになってしまいます。
「xlDelimited」等の定数を、「Const xlDelimited = 1」などと定義してありますか?

・Option Explicit宣言をしていない。
・Const定義がされていない。
・Excelオブジェクトを<object>などで「参照設定」していない。

上記の3条件すべてを満たしている場合、それらの値はEmpty値となりますので、正しく実行されないかと。

猫足 さん (halbal103@hotmail.com) 2004年 05月 12日 11時 40分 50秒

はじめまして。よろしく御願い致します

WSHでEXCELにテキストファイルを各列文字列として読み込みさせようとしています。
objXL.Workbooks.OpenText("xxxxxx.txt",,,xlDelimited,xlTextQualiferNone,,,,Comma,,,,Array(Array(2,2))
とすると「Subプロシージャーを呼び出すときに、括弧は使えない」とエラーになり、括弧を外すと「OpenTextメッソドが失敗しました」とエラーになってしまいます。
又、CSV形式を指定してファイルセーブ(SaveAs)も同様なエラーになります。
解決方法を御教授下さいますよう御願い致します。

Kenzo さん 2004年 05月 11日 22時 28分 25秒

TAPTAPさん、ごめんなさい。先にお返事頂いてたんですね。
私はVBAを真似てSaveChanges:=Trueにこだわってました。

魔界の仮面弁士さんも有難うございました。試して見ます。

これからも何卒よろしくお願い致します。

魔界の仮面弁士 さん 2004年 05月 11日 22時 07分 55秒

》 ばんのしゃーによかばんた さん
> wscの場合に、
> Private Sub Class_Initialize()
> は、そのまま書けばよさそうですが、
> Private Sub Class_Terminate()
> に相当するものはないのでしょうか。

うちでは、WSC内でクラスを定義しておき、それを利用しています。

<?xml version="1.0" encoding="UTF-8"?><package>
<component>
<public>
<method name="MyMethod" />
</public>
<script language="VBScript"><![CDATA[Option Explicit
Dim C
Set C = New MainComponent
Sub MyMethod()
C.MyMethod
End Sub

Class MainComponent
Private Sub Class_Initialize()
MsgBox CStr(Timer), vbInformation, "Class_Initialize"
End Sub

Public Sub MyMethod()
MsgBox CStr(Timer), vbOKOnly, "MyMethod"
End Sub

Private Sub Class_Terminate()
MsgBox CStr(Timer), vbExclamation, "Class_Terminate"
End Sub
End Class
']]></script>
</component>
</package>

ばんのしゃーによかばんた さん 2004年 05月 11日 20時 12分 28秒

classの場合は、
Private Sub Class_Initialize()

Private Sub Class_Terminate()
があります。

wscの場合に、
Private Sub Class_Initialize()
は、そのまま書けばよさそうですが、
Private Sub Class_Terminate()
に相当するものはないのでしょうか。

ところで、
cscript.exeの中に
WScript_OnScriptTerminate
という文字列が見えます。

Sub WScript_OnScriptTerminate()
とでも作っておけば、スクリプト終了時に呼び出されるかと思いましたが、
何も起こりませんでした。

はたまた、
wshext.dllの中に、
Advanced Settings - Windows Script Host
Please choose folder for #include directive
なんてのが見えます。
うーん、何だろう。

ばんのしゃーによかばんた さん 2004年 05月 11日 20時 11分 19秒

>ばんのしゃーによかばんた さん 2004年 05月 01日 18時 14分 18秒
>XLSファイルを作っておかなくても、動的にVBAを作り込めますね。
>IEでnavigate "about:blank"してdocument.write "<HTML>"するように。

Excelを利用したlogoff procedureです。

Excelのブックに標準モジュールを追加して、
Auto_Close()を書き込みます。
ログオフ時にExcelの終了処理が走り、Auto_Close()が呼び出されます。
ここにログオフ時のユーザ処理を記述しておくか、
ログオフ時のユーザ処理を呼び出せばよい。

Set xl=CreateObject("Excel.Application")
'xl.Visible=True
Set book=xl.WorkBooks.Add
Set VBProject=book.VBProject
Set VBComponent=VBProject.VBComponents.Add(1)
Set CodeModule=VBComponent.CodeModule
CodeModule.AddFromString("Sub Auto_Close()" & vbCRLF & "MsgBox ""Auto_Close""" & vbCRLF & "End Sub" & vbCRLF)
Set CodeModule=Nothing
Set VBComponent=Nothing
Set VBProject=Nothing
book.Saved=True
Set book=Nothing
Set xl=Nothing
WScript.Quit

Win2000では、問題なく動くのですが、
Win98SEでは、処理後、Excelの終了時に、なぜか異常終了します。
VBEを触ると、どうも異常終了するようなので、丁寧に解放しているのですが、
それでも駄目なようです。

魔界の仮面弁士 さん 2004年 05月 11日 18時 47分 38秒

> そうです。別セクションの人が頑張ってマクロとか使った力作
> だから触りたくありません。

プログラムで起動するのであれば、Workbooks.Openではなく、
Workbooks.Addで開くようにされては如何でしょう。
これなら、新規ブックとして開かれるので、元ファイルには影響が出ないかと。

もし、ダブルクリックでシートが開かれる可能性があるなら、
元ファイルをテンプレート形式(*.xlt)で保存しておくのも手だと思います。
これなら、ダブルクリックで起動しても、新規ブックになりますし。

Kenzo さん 2004年 05月 11日 18時 10分 59秒

いりやさん、TAPTAPさんレスありがとうございました。

> 実際に変更を加えたオリジナルはどうされるのでしょうか?
> それには、変更を反映させたくないということかな。。

そうです。別セクションの人が頑張ってマクロとか使った力作
だから触りたくありません。

この先はIntranetに乗せてオリジナルに値、今日の円レートなんで
すが、を自動的に毎日入れたコピー雛型をクライアントに使わせ
るような処理を考えてます。

VBAのオプション、SaveChanges :=True を何とかSaveAsなり
SaveCopyAsに渡そうとしたのですが駄目なので、ちょいと社外
を散歩して頭を冷やして来ました。

アメリカのサイトに何か手がかりはないか、探したら

The VB Script below saves information to an Excel spreadsheet.

===============================================================

Dim xlApp, xlBook, xlSht
Dim filename, value1, value2, value3, value4

on error resume next

filename = "c:\warehouse.xls"

Set xlApp = CreateObject("Excel.Application")
set xlBook = xlApp.WorkBooks.Open(filename)
set xlSht = xlApp.activesheet

' これが必要です。
xlApp.DisplayAlerts = False

'write data into the spreadsheet
xlSht.Cells(2, 2) = "New Data"

xlBook.Save
xlBook.Close SaveChanges=True
xlApp.Close
xlApp.Quit

'always deallocate after use...
set xlSht = Nothing
Set xlBook = Nothing
Set xlApp = Nothing

============================================================

これはオリジナルに書き込む処理ですが、私のObj.SaveAs "xxxxxxxx"
でも上手く行きました。ObjXL.DisplayAlerts = False' を書いておく
とうざいポップ・アップは回避出きます。

どうも一人相撲を演じたようでご迷惑をかけました。もう少しまとも
な質問が出きるように努力します。ご無礼お許し下さい。それでは又

TAPTAP さん 2004年 05月 11日 17時 50分 50秒

>いりやさん
うまくいきました!
下に
objX.activeworkbook.savecopyas "C:\My Documents\keisan\renbook2.xls"
objX.ActiveWorkbook.Saved = True
objX.ActiveWorkbook.Close
を付け加えると
オリジナルは無傷でした!あー勉強になった。
ってことでいいんでしょうか^^; Kenzoさんも。

Return