kenji さん 2004年 06月 02日 08時 57分 28秒

いりやさん、

おはようございます。うちはアメリカのCD-ROMがメインなんです。
雑誌・新聞類は大体半年毎に新しいものが入って来ますので、古いものが
欲しい、あれもこれも、となると数が増えてしまいます。

アメリカの電話帳はシングル扱いなのですが7枚組で総量は4GBを超えます。
向こうの人口は約日本の二倍だから約二億五千万人。電話の普及率は8割
とすると二億人のデーター量になります。

中には固定でしか動かないものや、動的でも予めドライブ名を指定する必
要があるのもあったりで、これらはZから逆に割り振り、残りを動的に使い
回しやり繰りしています。

数を増やすとアプリがインデックスをドライブ毎に読み込むのに少し時間が
かかりますが、お皿の内容をHDにコピーし物理的なデバイスの介在を避けて
ますので、複数クライアントからの負荷検索にも十分耐えられます。まあハ
ードとネットワーク性能にもよりますが。。。

データ−ベース・アプリの動向なんですがDVD等で大容量化も進んでますが、
通信インフラの整備・拡充によりWeb化の方がメインになりつつありますね。
そうなると楽なんですが私の領分がなくなってしまう。笑

以上ご参考まで。今後も宜しくお願い致します。

いりや さん 2004年 06月 01日 17時 28分 17秒

kenji さん、

応用プログラムのご説明、楽しんで読ませて頂きました。20 ドラ
イブもマップすることもあるとは驚きです。うちの会社の PC でも
共有ドライブをマップしていますが会社指定のものが五つか六つぐ
らいで個人でマップしているものも合わせてもその半分もいきませ
ん。アルファベット (A: 〜 Z:) ほとんど使っていますね!

| ネットワーク・リソースを複数使うものよりも一つしか使わないア
| プリの方が多く、テーブル・ファイルの数が増えて煩雑になるかと
| 思い躊躇しました。今後一つのマスター・テーブルから該当個所を
| 読み出すような処理を考えてみます。

アプリ毎にセクションを設けて値を保存する話は、まさに INI ファ
イルのそれと近いのかもしれません。保守性向上に役立つアイディ
アだとおもいます。

いりや

SUNY さん (uno@qq.emis.or.jp) 2004年 06月 01日 13時 30分 32秒

初めて書き込みます。WSH初心者です。最近覚えて使い始めました。
どうしてもわからないことがありましたので、質問します。ちょっと漠然とした
質問で申し訳ありませんが( ;^^)ヘ..

【質問内容】
FileExistsメソッドってワイルドカード使用できないんですね。
ファイルの存在チェックでそれに代わる関数ってあるのでしょうか?

要はDeleteFileメソッドでファイルを削除したいのです。
(↑このメソッドはワイルドカード使用可ですよね)
削除する前に存在チェックを行わないと、ファイルが存在しない場合エラーとなってしまいます。私が行いたい処理はファイルが存在したら削除、存在しなければスルーってな感じです。

よろしくお願いします。

wo さん 2004年 05月 31日 08時 42分 54秒

魔界の仮面弁士 さんありがとうございます
二重投稿してすみません
ここって投稿してから時間が経たないと載らないのですね

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

Class_Terminate二題

こんな使い方が出来ます。

甲案 try...finally擬に。

try {
AAA
} finally {
BBB
}
なら、

sub try()
dim f
Set f=new finally
AAA
end sub
call try()

class finally
private sub class_terminate()
BBB
end sub
end class

※ BBBはAAAのsubを抜けるときに実行される。
※ エラーが発生しても実行される。

乙案 エラーリカバリ、リソースパージに。

set fso=CreateObject("Scripting.FileSystemObject")
set r=new recovery
dim file
Set file=fso.CreateTextFile("AAA.TXT")
err.raise 5 '正常/異常でコメント切替
file.close
fso.DeleteFile("AAA.TXT")
set file=nothing

class recovery
private sub class_terminate()
msgbox join(array(err.Number,err.Description),vbCRLF)
if typename(file)="TextStream" Then
: : file.close
: : fso.DeleteFile("AAA.TXT")
end if
end sub
end class

※ エラーメッセージが出た後に、リカバリルーチンが走る。(正常終了時も走る。)
※ リカバリルーチンの中で、エラーコード/メッセージが参照出来る。

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

ロック、逐次化の方法です。

この方法の利点はスクリプトがエラーで中断しても、プロセス終了時に、
システムによって自動的にロックが解放されることです。

以下を多重に起動すると、シリアライズされている様子が分かります。

Option Explicit
Dim LockWord
Dim Sec
Dim oLock
Dim wShell

Set wShell=CreateObject("WScript.Shell")
LockWord=WScript.ScriptName
Sec=10
Set oLock=LockWait(LockWord,Sec)
If oLock Is Nothing Then
: : wShell.PopUp WScript.ScriptName & " can not run. Lock Failed - " & LockWord,10
: : WScript.Quit
End If
wShell.PopUp WScript.ScriptName & " started. Locked - " & LockWord,10
' Main Process
oLock.Close
wShell.PopUp WScript.ScriptName & " ended. Unlocked - " & LockWord,10
WScript.Quit


Function LockWait(LockWord,Sec)
: : Dim fso
: : Dim tFolder
: : Dim tName
: : Dim tPath
: : Dim tNum

: : Set fso=CreateObject("Scripting.FileSystemObject")
: : Set tFolder=fso.GetSpecialFolder(0)
: : Set tFolder=tFolder.SubFolders("Temp")
: : tName=UCase(LockWord) & ".LOCK"
: : tPath=fso.BuildPath(tFolder.Path,tName)
: : For tNum=0 To Sec
: : : : On Error Resume Next
: : : : fso.DeleteFile tPath
: : : : Err.Clear
: : : : Set LockWait=tFolder.CreateTextFile(tName)
: : : : If Err=0 Then Exit For
: : : : On Error GoTo 0
: : : : WScript.Sleep 1000
: : Next
: : If tNum>Sec Then Set LockWait=Nothing
End Function

※こんなインデントはどうでしょう。スペースに置換する必要はありません。
また、グリッド線みたいで、インデントが分かり易くなるという副作用も。
JScriptなら「; ; 」。

魔界の仮面弁士 さん 2004年 05月 30日 13時 53分 47秒

》 wo さん
MsgBoxのアイコンは5パターンあります。いずれか一つを指定できます。
 [なし]…未指定
 [情報(iのアイコン)]…vbInformation
 [確認・問い合わせ(?のアイコン)]…vbQuestion
 [注意(!のアイコン)]…vbExclamation
 [警告・エラー(×のアイコン)]…vbCritical


ボタンも、5パターンから選択する事になります。
ただし、それぞれにヘルプボタンの有無を選択できますので、
それも含めるならば 10パターンとなります。
 [OK]…vbOKOnly(または未指定)
 [はい,いいえ]…vbYesNo
 [はい,いいえ,キャンセル]…vbYesNoCancel
 [再試行,キャンセル]…vbRetryCancel
 [中止,再試行,無視]…vbAbortRetryIgnore

 [OK,ヘルプ]…vbMsgBoxHelpButton
 [はい,いいえ,ヘルプ]…vbYesNo Or vbMsgBoxHelpButton
 [はい,いいえ,キャンセル,ヘルプ]…vbYesNoCancel Or vbMsgBoxHelpButton
 [再試行,キャンセル,ヘルプ]…vbRetryCancel Or vbMsgBoxHelpButton
 [中止,再試行,無視,ヘルプ]…vbAbortRetryIgnore Or vbMsgBoxHelpButton


なお、VBScriptのMsgBox関数で、第4および第5引数を指定した場合は、
vbMsgBoxHelpButton フラグを明示せずとも、[ヘルプ]ボタンが表示されます。
(ただし、VB/VBAで[ヘルプ]を表示させる場合は、vbMsgBoxHelpButton が必須です)


VBScript版 MsgBox関数
http://www.microsoft.com/japan/msdn/library/ja/script56/html/vsfctmsgbox.asp

VB/VBA版 MsgBox関数
http://www.microsoft.com/JAPAN/developer/library/Vbenlr98/vafctMsgBox.htm

wo さん 2004年 05月 30日 11時 55分 03秒

このサイトで基礎を学びました。ありがとうございました!

質問なんですがMsgBox等で使うボタンやアイコンの種類はどのようなものがあるんですか?
じぶんでボタンの種類は確かめました。(おそらく)

wo さん 2004年 05月 30日 11時 52分 44秒

このサイトで基礎を学びました。ありがとうございます!

質問なんですが、MsgBox等でつかうボタンやアイコンの種類はどのようなものがあるんですか?
自分でボタンの種類は確かめられたと思います。

管理人むたぐち さん 2004年 05月 30日 00時 01分 26秒

For文の中でカウンタ変数をインクリメントしたり(これが怪しい
動作の元凶である気がする。普通こういうことはしない気が…)、
定数を宣言するのに、Constを使わずわざわざDimを使って
二度手間になっていたりして、かなりまともじゃないなこれは…。

管理人むたぐち さん 2004年 05月 29日 23時 47分 49秒

Windows Media Encoder 9
http://www.microsoft.com/japan/windows/windowsmedia/9series/encoder/default.aspx
を使って、WDMドライバで動くTVチューナーつきビデオキャプチャカードを制御して、
LAN内ストリーミング映像配信なんてことをやってみてます。

というのも、こいつにはWindows Media エンコード スクリプトという機能が
ついていて、要するにCOMでオートメーションできるんです。
もちろんWSHから制御可能です。

ヘルプファイル(詳しい)によると、別にフルスクラッチでスクリプトを書かなくても、
C:\program files\windows media components\encoder\WMCmd.vbsという
制御用スクリプトファイルがあらかじめ用意されており、これにコマンドライン
オプションをつけて実行すれば、たいていのことはできる…はずなのですが、
どうも挙動が変なんですね。
ヘルプにあるオプションを指定しても、invalid parameterですとか言われて怒られる。

で、WMCmd.vbsを覗いて見たんですが、CreateObjectもしてないのにいきなり、
WshShell.Popup
なんて行があったりして、「ああ、これはまともじゃないな…」と判断したので
ありました。なんか適当に作られてる予感がすごくします。
コマンドラインパラメーターの解釈部分がおかしいんじゃないかと思います。

これはWMCmd.vbsを解析しつつ、自分用のを作った方が早いかもしれません。

kenji さん 2004年 05月 29日 12時 43分 01秒

いりやさん、今日わ。この前ネットワーク・リソースの動的
マッピング方法を教えて頂いた者です。その後の状況ご報
告致しておきます。

むたぐちさんのかかれている Lesson 12 も再度読ませて頂きました。
http://www.roy.hi-ho.ne.jp/mutaguchi/wsh/refer/lesson12.htm

なおこのシステムを使用しているのはある専門図書館で来訪した方
の資料検索に自由に使ってもらってます。

色々考えたのですが、最初に教えて頂いた方式にエラー・トラップを
組み合わせるようにしました。入力は各スクリプトのショート・カッ
トをダブルクリックするのでエラーは起こりませんが、ネットワーク
絡みのエラーが起きた場合に切り分けし易いようにエラーの概要をポ
ップ・アップするようにしています。

アプリ毎にスクリプトを書いています。原則は1アプリに1ドライブ
ですが、中には20ドライブ位も使うものもあります。又古いDOSのアプ
リもあるので全体を一つにまとめるのは難しいです。

ネットワーク・リソースも割とよくアップデートや追加・削除がある
のでローカルとネットワークがペアになってるテーブルは分かりやす
いですね。

動的マッピングの他、固定でないと動かないものもありますのでこれら
にはマップだけのスクリプトを書きOS側の Scheduled Task に登録しユ
ーザがログインする際にマップをかけるようにしています。

以下拙作ご覧下さい。

On Error Resume Next

'オブジェクトの生成
Set WshNet = CreateObject("WScript.Network")
Set mapTable = CrateObject("Scripting.Directory")
Set WshShell = WScript.CreateObject("WScript.Shell")

initialize(mapTable) 'マップテーブルの初期化
Sub Initialize(mapTable) 'マップテーブルの生成
mapTable.Add. "G:", "\\server\share1"
mapTable.Add. "H:", "\\server\share2"
mapTable.Add. "I:", "\\server\share3"
End Sub

add(mapTable) 'マップテーブルの実行
Sub add(mapTable)
For Each localname In mapTable
remotename = mapTable.item(localname)
Wsh.Net.MapNetworkDrive localname, remotename
Next
End Sub

Select Case Err.Number 'エラー時の分岐処理

Case 0 '問題がなければアプリを起動
WshShell.Run """c:\xxx\yyy\zzz.exe""", 1, true

Case -2147024829 'ネットワーク・エラー
MsgBox "マップテーブルないし、マシンのネットワーク設定を調べて下さい", 16, "ネットワーク・エラー" 

Case -2147023665 'クライアント側ネットワークの物理的エラー
MsgBox "ネットワーク・カードないしケーブルを調べて下さい", 16, "クライアント側の物理的なネットワーク・エラー"

Case -2147024843 'サーバー停止状態
MsgBox "サーバーが起動していません。管理者に連絡して下さい", 16, "サーバー・ダウン"

Case Else '上記以外のエラー
MsgBox "管理者に連絡して下さい" & vbCrLf & vbCrLf & Err.Description & (Error 番号 = "& Err.Number &")", 16, "深刻なエラー"

End Select

remove(mapTable) 'マップの削除
Sub add(mapTable)
For Each localname In mapTable
remotename = mapTable.item(localname)
Wsh.Net.MapNetworkDrive localname, remotename
Next
End Sub

Set NetWsh = Nothing
Set maptable = Nothing
Set WshShell = Nothing


クラスで書いて下さったメソッドの中にマップテーブルを外部から
読み込む方式がありましたね。これを応用しようかと思いましたが
ネットワーク・リソースを複数使うものよりも一つしか使わないア
プリの方が多く、テーブル・ファイルの数が増えて煩雑になるかと
思い躊躇しました。今後一つのマスター・テーブルから該当個所を
読み出すような処理を考えてみます。

又見てくれなんですが、ショートカット・アイコンを直接触る代わ
りに、htmlなりhtaドキュメントにスクリプトへのリンクを書けば
すっきりしますが、これだとブラウザーがセキュリテイ上「開くか
ダウンロードするか」を聞いて来ますね。vbsはアイコン上では変え
られないのでレジストリーを触る必要があります。完全にクローズ
なLANであれば問題ありませんが、このシステムはルーターを介して
インターネットに繋がっているのであぶないです。これも今後の課
題です。

誠に簡単ではありますがいりやさんのスクリプト応用させて頂きま
した。ありがとうございます。

たけし さん 2004年 05月 27日 09時 00分 49秒

魔界の仮面弁士さん、いりやさん、むたぐちさん、

> 全角スペース及びデバッグ環境について

皆さん、プロの手の内を明かして頂きありがとうございました。

そうですね。ウインドウズにはオプションのスクリプト・エデイターもあ
るし、デバッガーもあるんでしたね。一時試してたんですが、あのエディ
ターは味気ないから使わなくなってしまいました。失敬忘れてました。私
も全角スペースを強調表示出来るエデイターにして見ます。

私の奥の手、英語版のエデイターで開き、日本語版から印字した内容と見
比べる。笑 最近目が悪くなり集中力も落ちて来たので画面勝負は辛いで
す。

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

>ばんのしゃーによかばんた さん 2004年 05月 19日 17時 39分 49秒
>IEのStatusBarのStatusTextを使ったProgressBar擬

この方法の利点。
(1) Navigateしないので速い。
(2) NavigateしないのでStatusBarが広く使える。
(3) 別プロセスでshll.Windowsで引っ掛けて更新、表示終了が出来る。

※IEをプロセス間でShared MemoryやPipeの代わりに使えますね。

したがって、例えば、バッチファイルの中から更新、表示終了の操作が出来る。

Progress バーセント
(バーセント%)■■■■■■■■■■□□□□□□□□□□

Progress 分子 分母
分子/分母(バーセント%)■■■■■■■■■■□□□□□□□□□□

Progress
表示終了。

---Progress.VBS---
Select Case(WScript.Arguments.Count)
Case 1:
p=WScript.Arguments(0)
m=20
k=p*20\100
Case 2:
k=WScript.Arguments(0)
m=WScript.Arguments(1)
p=k*100\m
End Select
If p>100 Then Err.Raise 6

Set shell=CreateObject("Shell.Application")
For Each ie In shell.Windows
If ie.busy=0 And ie.ReadyState=0 And ie.LocationName="" Then Exit For
Next
If IsEmpty(ie) Then
Set ie=CreateObject("InternetExplorer.Application")
ie.Top = 0
ie.Left = 0
ie.Height = 47
ie.AddressBar = False
ie.MenuBar = False
ie.ToolBar = False
ie.Resizable = False
ie.Visible=True
End IF
If WScript.Arguments.Count=0 Then
ie.Quit
Else
If WScript.Arguments.Count=1 Then
Text="(" & p & "%)" & String(k,"■") & String(20-k,"□")
Else
Text=k & "/" & m & "(" & p & "%)" & String(p*20\100,"■") & String(20-(p*20\100),"□")
End IF
L=20
For k=1 To Len(text)
c=Asc(Mid(text,k,1))
If c<0 Then L=L+12 Else L=L+6
Next
ie.Width = L
ie.StatusText=Text
End IF
---Progress.VBS---

※テキストの表示幅を計算する方法ってあるのでしょうか。

管理人むたぐち さん 2004年 05月 26日 17時 21分 24秒

To: バリバリ豊田です。 さん

> WSHにて、理由あってSHFileOperationAを用いてファイルコピーをしたいん
> ですが・・・。

そもそも、rundll32.exeでSHFileOperationAを呼び出せるんでしょうか?
ちょっとGoogleしてみましたが、それらしい例は無いようですね。
rundll32.exeって汎用的なDLL関数呼び出しプログラムなんでしたっけ?

WSHからシェルの機能を使って、ファイルコピーするなら、Shell.Application
を用いるのが一般的だと思います。
詳しくは、http://www.roy.hi-ho.ne.jp/mutaguchi/wsh/object/shell.htmや、
ここ数日の掲示板の書き込みなどを参考にしてください。


To: たけし さん

> 全角スペース

私も魔界の仮面弁士さんやいりやさんと同じで、全角スペースを強調表示できる
エディタを使っています。

デバッグは、そもそもデバッグするような長いスクリプトは書かないので、
デバッガのようなものは使ってません。
Windows Scriptには、スクリプトデバッガがあるんですけどね。


To: 魔界の仮面弁士 さん

> white-space対策

Hi-HO謹製のスクリプトを弄って良いのかとか、AKiOSさんの検索用HTAに
不具合が出ないかとか、色々あって未だに対策してません。

CGIの出力そのものを変更せずに、スクリプト/CSSだけで実現する方法、
何かないでしょうか?
<head>内は自由に変更できます。

いりや さん 2004年 05月 26日 14時 36分 32秒

たけしさん、魔界の仮面弁士さん、

| > 皆さんデバッグはどのような方法をお使いですか?
| 私の場合、VBScriptやJScriptの WSHのデバッグには、
| Visual Studio.NET 2003を使うことが多いです。

わたしは数十行でかたがつくプログラムを扱う場合が多くエディタと実行環境
(wscript.exe, cscript.exe) で済ませています。ただ Component Object Model
を取り扱う場合はもう少し突っ込んだ情報を必要とすることがあってそういう場
合はインスペクタ (Inspector) に相当するものがほしいなぁと感じます。
Dynamic HTML Objct Model などのような木構造を内包するオブジェクトなどは
インスペクタがないのは正直つらい。

それから、全角表示が誤って混入したが見当たらない件わたしも経験があります。

掲示板に投函する場合は、タブコードを全角スペース四つに置き換えるスクリプ
トでコードを変換しているので、逆変換をスクリプトで行って誤って混入するこ
とを避けています。

それでほぼ救えますが、たまに気づかないこともあります。そうした場合はエディ
タの着色機能を利用しています。

わたしが使っている K2Editor にはそうした機能があり、さらに標準で .vbs,
.js ファイル向けの設定が組み込まれています。背景色が赤色ですから目に飛び
込んできます。チカチカするけれど効果抜群です。次のスナップショットは編集
中の画面です。

http://iriyak.adam.ne.jp/arc/uwsc/ZenkakuInK2Editor.png

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

この掲示板、white-space対策がとられていないので、
半角空白でのインデントが行えないんですよね…。(^^;

JScriptなら、全角空白でインデントしても問題無いのですが、
VBScriptだと全角空白は使えないので、悩ましい所です。

> スペースは普通のエディターでは分かり辛い。
秀丸とかVisual Studio.NETなどでは、オプション指定によって
「タブ文字」「全角空白」を可読できるように設定できますので、
私はそれを利用しています。

> ちなみに私はバイナリ−・エディターで全角スペース81,40を半角20に置換
> するようにしています。
プログラム的に、単純に一括置換できない場合もあるので、個別に置換していく必要がありますね。

S1 = Asc(" ") '全角空白
S2 = Asc(" ") '半角空白

> 皆さんデバッグはどのような方法をお使いですか?
私の場合、VBScriptやJScriptの WSHのデバッグには、
Visual Studio.NET 2003を使うことが多いです。

たけし さん 2004年 05月 26日 10時 32分 56秒

ある方のコメントから引用させて頂きますと、

※ 例によって全角スペースは半角スペースに置き換えてから実行ください。

コードを書いている時に全角、半角の扱いは中々厄介ですね。文字・数字
なら見た目で分かることもありますが、スペースは普通のエディターでは分
かり辛い。思わぬ所に全角スペースが残っていて苦労したこともあります。

皆さんデバッグはどのような方法をお使いですか?

ちなみに私はバイナリ−・エディターで全角スペース81,40を半角20に置換
するようにしています。

MAKOTO さん 2004年 05月 26日 09時 48分 56秒

to 管理人むたぐち

教えていただいた方法で問題なく出来ました。
ただ、私はひたすら「???」です。

この方法で手直ししてやったつもりだったんですけど。
どっか、間違えて記述してたみたいです。

うーん、恥ずかしい。
やってる事すら、チャチなのでいまさらですが(^^)

早いこと、VBSの書籍を購入しに行ってきます。

有難うございました。

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

>To: ゆぎ さん
>> あるアプリケーションを実行するVBSを作りました。
>> その実行中に、ほかのアプリケーションやらなにやらを、
>> 実行できないようにしたいのですが、実現可能でしょうか?

ロック、逐次化の話ではなく、単にユーザの他の操作を抑止したいのなら、
例えば、こういうのはどうでしょう。目眩ましですが、素人は騙せるかも知れません。

Set ie=CreateObject("InternetExplorer.Application")
ie.Navigate "about:blank"
Do While ie.Busy Or ie.ReadyState<>4
WScript.Sleep 100
Loop
ie.Document.bgcolor="#008080"
ie.Document.body.scroll="no"
ie.Document.body.style.border="none"
ie.Fullscreen=true
ie.Visible=True
Set wShell=CreateObject("WScript.Shell")
Set oExec=wShell.Exec("Notepad")
Do While oExec.Status=0
If ie.Document.HasFocus() Then wShell.AppActivate oExec.ProcessID
WScript.Sleep 100
Loop
ie.Quit
WScript.Quit

バリバリ豊田です。 さん 2004年 05月 25日 17時 55分 59秒

バリバリ豊田です。

分かる方がいらしたら、教えて下さい。
WSHにて、理由あってSHFileOperationAを用いてファイルコピーをしたいん
ですが・・・。下記部分の引数の書き方が分かりません。

Set WShell = CreateObject("WScript.Shell")
WShell.Run("rundll32.exe shell32.dll,SHFileOperationA [hwnd &H2] [D:\test\a\!GIR2.TIF] [D:\test\b\!GIR2.TIF]")

どなたかわかりましたら宜しくお願いします。

Kenzo さん 2004年 05月 25日 09時 05分 10秒

ばんのしゃーによかばんた さん、

> このような場合、オリジナルを別名にコピーし、コピー先を編集して
> 上書き保存するようにしたほうが、堅牢(安全確実)です。

ありがとうございます。皆様方よりアドバイス頂き納得が行くものが出
来ました。依頼元からあれこれ注文が付くかも知れませんが、その時は
又お知恵拝借させて下さい。

御礼まで。

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

>Kenzo さん 2004年 05月 11日 10時 29分 35秒
> VBでエクセルの自動処理を書いてます。別のファイルから読み込んだ値
> を特定のレンジに挿入してオリジナルを別名で保存するものです。
> ExcelObj.ActiveWorkbook.SaveAs "c:\aaa\bbb\ccc.xls"
> で 、VBSを実行すると既にファイルがあると上書きするか聞いてきます。
> これを回避したいのですが、VBでは、実行を強制するTrue, Falseの指定
> は出来なかったのでしょうか?

このような場合、
オリジナルを別名にコピーし、コピー先を編集して上書き保存するようにしたほうが、
堅牢(安全確実)です。

いりや さん 2004年 05月 24日 16時 25分 11秒

kenji さん、

| サーバー側が受け取れる文字数に制限があるのが分かりましたが、べたに書
| いている時は大丈夫なのに配列から渡すと問題が起きる。さてはと思い、後
| 始末、Set WshNet = Nothing をきっちり全部に入れて、オブジェクトを開放
| するようにすると消えました。

なるほど、これはなかなか切り分けの難しいやっかいな事象ですね〜。

kenji さん 2004年 05月 24日 09時 22分 49秒

いりやさん、

引き続きご教授頂き実にありがとうございます。

> すでに kenji さんは鋭く見抜かれていますが。。。

滅相もない。私はきれいなコーディングが出来るほどの技量がないので一通
り動くようになればエラー処理だけはきっちりするように心がけています。

いりやさんのように最初からロジックをがっちり組んでおき、ローカル・
ドライブとネットワーク・リソースの対応付けを外部ファイルから取り込む
ようにしておけばまず問題は起こらないと思いますが、まず何らかの理由で
マップが残った場合の処理を頭に付けようと考えました。

Dim WshNet
Set WshNet = WshNet("WScript.Network")
Set objDrives = WshNet.EnumNetworkDrives

For i = 0 to objDrives.Count -1 Step 2
WshNet.RemoveNetworkDrive objDrives.item(i)
Next

何故かある時点で「パラメーターが違います。」というエラーを吐いてそれ
以上マップを外せなくなり止まってしまいました。エラーコード 277801を
マイクソフトのサポートURLで確かめてみると、

http://support.microsoft.com/default.aspx?scid=kb;JA;277801

原因

この問題は、"ホスト側の" MCU サーバー上のリモート サイトの [ネットワ
ーク名を使用]ボックスに、32 文字を超える完全修飾ドメイン名 (FQDN) が
入力された場合に発生する可能性があります。リモート サイトにあるクライ
アントはデータ会議に参加できず、この資料の「現象」に記載するエラー メ
ッセージが表示されます。

ホスト サーバーが "リモートの" MCU 接続情報をクライアントに渡すときの
文字数は、最大 32 文字まで許可されています。FQDN の文字数がこの制限を
超えると、参照は正常に行われません。

回避策

この問題を回避するには、短い名前のドメインに MCU を移動するか、MCU の
ホスト名を、FQDN が 32 文字以下になるよう変更します。

サーバー側が受け取れる文字数に制限があるのが分かりましたが、べたに書
いている時は大丈夫なのに配列から渡すと問題が起きる。さてはと思い、後
始末、Set WshNet = Nothing をきっちり全部に入れて、オブジェクトを開放
するようにすると消えました。

基本的な事をおろそかにしてました。お恥ずかしい。

亜紀 さん (freebirds@inter7.jp) 2004年 05月 22日 19時 53分 39秒

24歳の人妻です。主人とは深刻な倦怠期で会話もないし
半年間セックスレス…ストレス溜まりまくりです。
こんな私を精神的にも肉体的にも満たしてくれませんか?
誠実で優しい方を希望します。割り切りOK!秘密厳守で
お願いします。

いりや さん 2004年 05月 22日 18時 27分 17秒

むたぐちさん、

| こういうのは私も構想だけはありましたが、実際は面倒だったので
| 作らなかったんですが、見事、完成してますね。
| WSCだけで構築してあるところが美しいと思います。
|
| UWSCからの使用法がサンプルとして挙げられていますが、
| COMのインターフェースをサポートする言語・スクリプトって
| たくさんありますし、特にVBSの関数を呼び出したい時に重宝するのでは
| ないでしょうか。

しきさんもそんなことをおっしゃっていました。例えば UWSC だと利用できるデー
タ型が代表的なものに限られているので、COM のインターフェイスを通じて
VBScript や JScript の世界と交信して、その世界のオブジェクトと対話されて
いました。

私はまだそこまで二つの世界を相互に行き来することはなく、大概は引数をメッ
セージの代わりに渡して wscript.exe プロセスとしてスクリプトを起動するぐ
らいでしょうか。あるいはファイルをコミュニケーション・チャネルに使ってと
いう場合が多いです。でもこの二つだけだとやぼったく感じてきたので何かない
か模索中です。(.NET の世界にそろそろ移行しこうかしらん。)

いりや さん 2004年 05月 22日 18時 05分 16秒

|     Public Sub RemoveAll
|         For Each localname In mapTable
|             If FileSystemObject.DriveExists(localname) Then
|                 WScriptNetwork.RemoveNetworkDrive localname, true, true
|             End If
|         Next
|     End Sub

あれ? 解放後に mapTable の全エントリを削除する行がいつのまにか消えていま
す (苦笑)

正しくは、

    Public Sub RemoveAll
        For Each localname In mapTable
            If FileSystemObject.DriveExists(localname) Then
                WScriptNetwork.RemoveNetworkDrive localname, true, true
            End If
        Next
        mapTable.removeAll
    End Sub

でした。お詫びして訂正いたします。

いりや さん 2004年 05月 22日 17時 50分 58秒

kenji さん、

| 拝見しているといりやさんは本当に基本に忠実で分かり易く応用しやすいコ
| ードを書いて下さいますね。アプリの部分やエラーチェックを付け加えて全
| 体を仕上げて見ます。

すでに kenji さんは鋭く見抜かれていますが、わたし自身がご紹介するスクリ
プトのエラーチェックは必要最小限にとどめることが多いです。特に境界値と意
図しない入力に対する配慮が落ちています。より強固なものになるよう仕上げて
頂ければうれしいです。

ところで、さきにご紹介したスクリプトを Class 構文を用いて書き直してみま
した。ご参考までにどうぞ。普段 JScript でプログラミングをしているのでス
タイルが VisualBasic になじまれている方にとっては違和感があるかもしれま
せん。ご指摘いただければ幸いです。

※ 例によって全角スペースは半角スペースに置き換えてから実行ください。
※ example1 〜 example5 プロシージャを一つだけコメントアウトして実行しま
  す。サーバ名といった環境に依存した情報の修正はあらかじめしておいてく
  ださい。

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

'example1
'example2
'example3
'example4
'example5

'
' example1
'
' 実行時に三つのリモートディスクを接続、解放を順番に行う例題。
' 以下のメソッドを使用する。
' NetworkDriveAdministrator>>Register メソッド
' NetworkDriveAdministrator>>MapAll メソッド
' NetworkDriveAdministrator>>ShowMapTable メソッド
' NetworkDriveAdministrator.RemoveAll メソッド

Sub example1
    Set admin = New NetworkDriveAdministrator

    admin.Register "X:", "\\server1\sharename1"
    admin.Register "Y:", "\\server1\sharename2"
    admin.Register "Z:", "\\server1\sharename3"

    admin.MapAll
    WScript.Echo "接続を完了しました。接続状況を確認ください"
    admin.ShowMapTable

    admin.RemoveAll
    WScript.Echo "接続を解放しました"

    Set admin = Nothing
End Sub

' example2
'
' 実行時に一つのリモートディスクを接続、解放を順番に行う例題。
' 以下のメソッドを使用する。
' NetworkDriveAdministrator>>Map メソッド
' NetworkDriveAdministrator>>Remove メソッド

Sub example2
    Set admin = New NetworkDriveAdministrator

    admin.Map "X:", "\\server1\sharename1"
    WScript.Echo "接続を完了しました。接続状況を確認ください"
    admin.ShowMapTable

    admin.Remove "X:"
    WScript.Echo "接続を解放しました"

    Set admin = Nothing
End Sub

' example3
'
' マップ情報 (ローカルネームとリモートネームの対) をファイル
' に書き出す例題。(ファイルはタブで区切られた行で構成される)
' 以下のメソッドを使用する。
' NetworkDriveAdministrator>>ExportTo メソッド

Sub example3
    Set admin = New NetworkDriveAdministrator

    admin.Register "X:", "\\server1\sharename1"
    admin.Register "Y:", "\\server1\sharename2"
    admin.Register "Z:", "\\server1\sharename3"
    admin.ExportTo(".\fstab.txt")

    Set admin = Nothing
End Sub

' example4
'
' マップ情報 (ローカルネームとリモートネームの対) をファイル
' から取り込み、その情報をもとに、接続、開放を順番に行う例題。(ファイルはタブで区切られた行で構成される)
' 以下のメソッドを使用する。
' NetworkDriveAdministrator>>ImportFrom メソッド

Sub example4
    Set admin = New NetworkDriveAdministrator

    admin.ImportFrom(".\fstab.txt")
    admin.ShowMapTable

    admin.MapAll
    WScript.Echo "接続を完了しました。接続状況を確認ください"
    admin.ShowMapTable

    admin.RemoveAll
    WScript.Echo "接続を解放しました"

    Set admin = Nothing
End Sub

' example5
'
' example4 と同様のシナリオだが、ファイル名を example4 のように
' ハード・コーディングするのではなくて、スクリプトファイルにドラッグ
' &ドロップされたファイルを取り込む。

Sub example5
    Set admin = New NetworkDriveAdministrator

    If WScript.Arguments.Count <> 1 Then
        WScript.Echo("ファイルを1個ドラッグ&ドロップください")
        WScript.Quit
    Else
        filepath = WScript.Arguments(0)
        admin.ImportFrom(filepath)
        admin.ShowMapTable

        admin.MapAll
        WScript.Echo "接続を完了しました。接続状況を確認ください"
        admin.ShowMapTable

        admin.RemoveAll
        WScript.Echo "接続を解放しました"
    End If
    
    Set admin = Nothing
End Sub

Class NetworkDriveAdministrator
    Private mapTable
    Private WScriptNetwork
    Private FileSystemObject
    Private Sub Class_Initialize
        Set mapTable = CreateObject("Scripting.Dictionary")
        Set FileSystemObject = CreateObject("Scripting.FileSystemObject")
        Set WScriptNetwork = WScript.CreateObject("WScript.Network")
    End Sub
    Private Sub Class_Terminate
        Set mapTable = Nothing
        Set WScriptNetwork = Nothing
        Set FileSystemObject = Nothing
    End Sub
    Public Sub ShowMapTable
        s = "現在の MapTable の設定は次の通りです。" & vbCRLF & vbCRLF
        For Each localname In mapTable
            s = s & localname & " " & mapTable.Item(localname) & vbCRLF
        Next
        WScript.Echo s
    End Sub
    Public Sub ExportTo(filepath)
        If Not FileSystemObject.FileExists(filepath) then
            Set writeStream = FileSystemObject.CreateTextFile(filepath, true)
        else
            Set writeStream = FileSystemObject.OpenTextFile(filepath, 2, false)
        End If
        For Each localname In mapTable
            remotename = mapTable.Item(localname)
            writeStream.WriteLine localname & vbTab & remotename
        Next
        writeStream.close
    End Sub
    Public Sub ImportFrom(filepath)
        If FileSystemObject.FileExists(filepath) then
            Set readStream = FileSystemObject.OpenTextFile(filepath, 1, false)
            While Not readStream.AtEndOfStream
                stringArray = Split(readStream.readLine, vbTab)
                localname = stringArray(0)
                remotename = stringArray(1)
                mapTable.Add localname, remotename
            Wend
            readStream.Close
        End If
    End Sub
    Public Sub Register(localname, remotename)
        If mapTable.Exists(localname) Then
            mapTable.Remove localname
        End If
        mapTable.Add localname, remotename
    End Sub
    Public Sub unregister(localname)
        If mapTable.Exists(localname) Then
            mapTable.Remove localname
        End If
    End Sub
    Public Sub Map(localname, remotename)
        If Not FileSystemObject.DriveExists(localname) Then
            WScriptNetwork.MapNetworkDrive localname, remotename
            Register localname, remotename
        End If
    End Sub
    Public Sub MapAll
        For Each localname In mapTable
            remotename = mapTable.Item(localname)
            If Not FileSystemObject.DriveExists(localname) Then
                WScriptNetwork.MapNetworkDrive localname, remotename
            End If
        Next
    End Sub
    Public Sub Remove(localname)
        If FileSystemObject.DriveExists(localname) Then
            WScriptNetwork.RemoveNetworkDrive localname, true, true
            Unregister localname
        End If
    End Sub
    Public Sub RemoveAll
        For Each localname In mapTable
            If FileSystemObject.DriveExists(localname) Then
                WScriptNetwork.RemoveNetworkDrive localname, true, true
            End If
        Next
    End Sub
End Class

管理人むたぐち さん 2004年 05月 22日 07時 51分 05秒

ちょっと下の記事に修正です。

"FolderItems3"でGoogleを検索したところ、
http://www.roy.hi-ho.ne.jp/mutaguchi/bbs/list24.shtml
によると(ってうちですけど)、FolderItems3オブジェクトは、
IE5.5から追加されるオブジェクトということになります。

つまり、Win2000+IE5.5や6.0では使えるが、
Win2000+IE5.0や5.01だと使えないということになりますね。

MeにはIE5.5が、XPにはIE6.0が最初から入っているので、
何もせずに使えるということです。

ちなみにWin98だと、shell32.dllのバージョンが5.0未満なので、
IEのバージョンに関係なく、そもそも使えないということになります。

非常にややこしいですが、そういう対応になります。
(よってMSDNのFolderItems3オブジェクトのリファレンスは間違いではなかった)

管理人むたぐち さん 2004年 05月 22日 01時 28分 03秒

To: まっさ さん

> 実はWindows2000で動かしたときに
> 『oSFolderItems.Filter &H40,"*.*"』
> の行で

> となってエラーで終了してしまいます。

あ、失礼しました。
Filterメソッドのある、FolderItems3オブジェクトは、WinXPから
使用できるのでした。
(リファレンスのバージョン表記が間違ってるな…)

確認になりますが、まっささんが最初に書かれたコード
(Filterメソッドではなく、CopyHereメソッドの引数に
ワイルドカードを指定したもの)は、Win2000でも正常動作
しないんでしょうか?


To: MAKOTO さん

> これを手直しして、特定のフォルダをCドライブ直下へ
> コピーするようにしたいのですが、上手くいきません。

sFolder="C:\"
dFile="特定のフォルダのパス"
でうまくいかないということでしょうか?


To: いりや さん

> SkScript

こういうのは私も構想だけはありましたが、実際は面倒だったので
作らなかったんですが、見事、完成してますね。
WSCだけで構築してあるところが美しいと思います。

UWSCからの使用法がサンプルとして挙げられていますが、
COMのインターフェースをサポートする言語・スクリプトって
たくさんありますし、特にVBSの関数を呼び出したい時に重宝するのでは
ないでしょうか。

VBSの関数は、意外と使いでのあるものが多かったりしますからね。

kimiok さん 2004年 05月 20日 21時 49分 08秒

To : いりやさん

>  DateAdd
>  DateDiff
>  DatePart
>  DdateValue
>この四つが見つかりました。これらを使って「1日経過した日付を
>得る」ための手続きを考えてみてはいかがでしょうか。

早速のアドバイスありがとうございます。
再度確認し、報告をさせていただきます。
宜しくお願い致します。



いりや さん 2004年 05月 20日 21時 25分 30秒

http://www.tees.ne.jp/~rdat32lp/script/script.html

こちらでダウンロードできます。オンラインマニュアルも
充実しています。

いりや さん 2004年 05月 20日 21時 24分 24秒

ばんのしゃーによかばんたさん、

> こうまでなると、どこからどこまでがJscriptのこっちゃ、VBScriptのこっちゃ、分からん。

こうしたプログラム言語の相互利用については、わたしは S.K.
(しき) さんの Windows Script Component の SkScript をみて初
めて知りました。面白いトピックスですよね。

よい機会ですので、簡単に SkScript のことをご紹介しましょう。

SkScript の特徴は、大きく二つあって、一つは VBScript,
JScript プログラム言語のもつ組み込みオブジェクトの機能のほと
んどのものを提供していること。もう一つは、Windows Script
Component として提供されているので、Component Object Model
のインターフェイスをサポートするどんな環境でも利用できるとい
うところです。

お互いに足りないところを補いながらプログラミングするのに大変
役立つライブラリの一つではないか、と思います。

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

>管理人むたぐち さん 2004年 05月 18日 20時 46分 45秒
>ただ一つだけ気になるのは、ScriptControlは標準環境で使用できる
>のかってことです。Microsoftの開発環境がなくても大丈夫でしたっけ。

は、

>つちや さん 2003年 11月 26日 22時 21分 02秒
>Windows2000かMe以降じゃないとMSScriptControlが使えないかも。
>(その場合は、MSサイトからダウンロードすることが可能です。)

とのことです。

ただし、2000などの標準環境ではヘルプが付いてないので、
作る側はダウンロードしたほうがよいでしょう。

更にScriptControlの応用。再び、ソートです。

Set SC = CreateObject("ScriptControl")
SC.Language = "JScript"
Set a=SC.eval("new Array()")
call a.push("お","あ","え","い","う")
WScript.Echo a.length
WScript.Echo a
Set js=a.sort()
WScript.Echo js
WScript.Echo TypeName(js)
WScript.Echo js.length
For Each item In js
WScript.Echo item
Next

こうまでなると、どこからどこまでがJscriptのこっちゃ、VBScriptのこっちゃ、分からん。
これからはVBJScriptと呼びましょう。:-)

ところで、
JScript Arrayにindexでアクセスするには、AddCodeするしかないかな。

Call SC.AddCode("function getItem(a,i){return(a[i]);}")
For k=0 To js.length-1
WScript.Echo k,SC.Run("getItem",js,k)
Next

或いは、あまりエレガントでないが、evalで、

Set SC = CreateObject("ScriptControl")
SC.Language = "JScript"
Set a=SC.eval("var a=new Array();a")
call a.push("お","あ","え","い","う")
Set js=a.sort()
For k=0 To js.length-1
WScript.Echo k,SC.eval("a[" & k & "]")
Next

MAKOTO さん 2004年 05月 20日 20時 54分 46秒

以前、こちらのHPを参考にして
特定のファイルをFDにコピーするスクリプトを作らせてもらいました。

Dim sFolder,dFile
sFolder="a:\"
dFile="C:\Bootlog.txt"
Set Shell = WScript.CreateObject("Shell.Application")
Set oFolder=Shell.NameSpace(sFolder)
oFolder.CopyHere dFile

これを手直しして、特定のフォルダをCドライブ直下へ
コピーするようにしたいのですが、上手くいきません。

どこら辺りを訂正したら良いか良ければ教えていただけませんでしょうか?

いりや さん 2004年 05月 20日 19時 41分 36秒

kimiok さん、

CDATE() 関数の返すデータ型は、マニュアル (後述リファレンス参
照) によれば subtype が Date の Variant 型だそうです。でかつ
+ 演算子を見ると両辺に subtype が Date の場合の明記がないの
で、両辺に置ける値としては受け付けてくれないのかもしれません。

じゃ、subtype Data のデータの加算、減算を行う関数はないのか
と、調べてみたら

  DateAdd
  DateDiff
  DatePart
  DdateValue

この四つが見つかりました。これらを使って「1日経過した日付を
得る」ための手続きを考えてみてはいかがでしょうか。

[ リファレンス ]

msdn, + 演算子:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/vsopradd.asp

msdn, CDate() 関数:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/vsfctcdate.asp

msdn, DateAdd() 関数:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/vsfctDateAdd.asp

kimiok さん 2004年 05月 20日 18時 15分 38秒

始めまして。初心者のkimiokと申します。
これからですが、WSH を学びシステム運用に役立てていきたいと思います。

恐れ入りますが、下記の点についてご教示いただければ幸いです。

イベントログを特定の期間分 (例:4/1〜4/30まで) を取得し、
".evt"形式でローカル保存したいと考えております。
".evt"形式での保存方法は確認できたのですが、期間を指定するところでおきな壁にぶつかっています。

いろいろ調べ、Microsoft のスクリプトセンターで以下のサンプルを見つけました。この構文の中の日付と
「dtmEndDate.SetVarDate DateToCheck + 1」の"+1"の数値を単純に変更してみたのですが、全てのログが抽出される結果となりました。
もし皆様の中で何かアドバイスいただけることがございましたら
ご教示いただけまうようお願い致します。

[Sample]
=============================================================
Const CONVERT_TO_LOCAL_TIME = True
Set dtmStartDate = CreateObject("WbemScripting.SWbemDateTime")
Set dtmEndDate = CreateObject("WbemScripting.SWbemDateTime")
DateToCheck = CDate("2/18/2002")
dtmStartDate.SetVarDate DateToCheck, CONVERT_TO_LOCAL_TIME
dtmEndDate.SetVarDate DateToCheck + 1, CONVERT_TO_LOCAL_TIME
=============================================================

まっさ さん 2004年 05月 20日 18時 09分 37秒

>>管理人むたぐち様

さっそくまた来てしまいました。
前回の管理人さんの回答で実際にワイルドカード使用での
経過ダイアログ表示のコピーが正常に動いたのですが
それはWindowsXP Pro上での話でした・・・

実はWindows2000で動かしたときに
『oSFolderItems.Filter &H40,"*.*"』
の行で
*************************************************************
エラー: オブジェクトでサポートされていない
    プロパティまたはメソッドです。: 'oSFolderItems.Filter'
コード: 800A01B6
*************************************************************
となってエラーで終了してしまいます。

Windows Scriptのバージョンが古いからかと思い、
WSH5.6(scriptjp.exe)をダウンロードしてインストールをしても
同様でした・・・
なぜなんでしょうか? シクシク(;_;)


まっさ さん 2004年 05月 20日 14時 20分 08秒

>>管理人むたぐち様

詳細で分かりやすい説明に非常に感謝しております。
処理の方も期待通りの動きをしてくれました。
これからも、ちょくちょく来させてもらいますので
よろしくお願いいたします。

yos さん 2004年 05月 20日 14時 12分 20秒

>>管理人むたぐち さん

お返事ありがとうございます。

なるほどそういうことでしたか。
#でも、スクリプト・ホストの明示がなくとも起動はされるが、
#オプションは読み込まれない、というのも妙な感じですね。

稚拙な質問、失礼いたしました。

管理人むたぐち さん 2004年 05月 20日 12時 27分 04秒

To: まっさ さん

今、こちら(WinXP)で確認したところ、たしかにワイルドカードが
効きませんね。他のOSを使用されてる方、検証お願いします。
いつの間にか仕様が変わったのでしょうか。

CopyHereメソッドには第二引数があり、Const FOF_FILESONLY = &H80を
指定すれば「ワイルドカードを指定したとき(*.*)、フォルダを対象外にする」
ことが可能なはずなので、ワイルドカードが使えて当然なんですが
おかしいな。

仕方が無いので、ちょっと面倒なコードを書いてしのいでみました。

Set Shell = WScript.CreateObject("Shell.Application")
Set oRFolder=Shell.NameSpace("D:\receive\") '受け側フォルダ
Set oSFolder=Shell.NameSpace("D:\Send\") '送り側フォルダ
oRFolder.CopyHere oSFolder.Items
MsgBox "完了"

これだとフォルダまでコピー対象になるので、ファイルだけをコピーするには、

Set Shell = WScript.CreateObject("Shell.Application")
Set oRFolder=Shell.NameSpace("D:\receive\") '受け側フォルダ
Set oSFolder=Shell.NameSpace("D:\Send\") '送り側フォルダ
Set oSFolderItems=oSFolder.Items
oSFolderItems.Filter &H40,"*.*"
oRFolder.CopyHere oSFolderItems
MsgBox "完了"

となります。
ちなみに、Filterメソッドの第一引数を&H20にすると、フォルダだけがコピーされます。
第二引数は"*.*"のほか、"*.txt"など、拡張子でフィルタもできます。

Filterメソッドは、FolderItems3オブジェクトのメソッドで、
その名の通り、FileItemsコレクションの絞込みに使います。
Win2000, XPで使用可。
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/objects/folderitems3/filter.asp

第一引数に指定する、SHCONTF列挙型はこんな感じみたいです。

Const SHCONTF_FOLDERS = &H20 'フォルダだけに絞り込む
Const SHCONTF_NONFOLDERS = &H40 'ファイルだけに絞り込む
Const SHCONTF_INCLUDEHIDDEN = '隠しファイルのみ?
Const SHCONTF_INIT_ON_FIRST_NEXT = '?
Const SHCONTF_NETPRINTERSRCH = 'プリンタのみ?
Const SHCONTF_SHAREABLE = '共有フォルダのみ?
Const SHCONTF_STORAGE = 'ストレージ(?)のみ?

他の定数値はまだ調べていませんが(どうやって調べればいいのか?)、
とりあえず&H20と&H40さえ分かれば、実用上は困らないでしょう。

おかげで、ついにFilterメソッドの使い方が分かりました。

kenji さん 2004年 05月 20日 12時 17分 38秒

いりやさん、魔界の仮面弁士さん、

昨日は貴重なアドバイス頂き実に有難うございました。結果報告致します。

結論は私が最初に考えた方法、配列から引数を渡しループさせる、も正しか
ったのですが、渡し方が間違ってました。仮面弁士さんがおっしゃる通りで
そんなに難しく考えなくともよかったのです。VB風に引用符沢山付けて馬鹿
でした。以下完動スクリプトです。

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

'配列の作成
dat_1 = array("G:", "H:", "I:")
dat_2 = array("index-1", "index-2", "index-3")

For i = 0 to 2 '0から始まるので実配列数マイナス1
WshNet.MapNetworkDrive dat_1(i), "\\server\" & dat_2(i)
Next

それとコード以外に気が付いたのですが接続が以前に比べると凄く遅くな
ってました。以前だと一呼吸位で繋がったのですが、今は「おい、おい、
おい、一体どうなってるの」と我慢しきれなくなる頃に繋がります。大き
なネットワークの一部なんです。昨日は知らずにカリカリしてました。

ネットワークの負荷なのかサーバーがへたってるのか、私のマシンがウイ
ルスにでもやられてるのか切り分けられないので、今朝はサーバー・ルー
ムに篭って短い経路でやると小気味良く繋がってくれます。

いりやさんはDictionaryオブジェクトを使ったプロシージャー形式の完全な
コードをご提供下さりとても感謝しております。テーブル形式に引数をペア
にしておくとメンテする際も分かり易く間違いも起こしにくいので出先の人
は喜ぶでしょう。

拝見しているといりやさんは本当に基本に忠実で分かり易く応用しやすいコ
ードを書いて下さいますね。アプリの部分やエラーチェックを付け加えて全
体を仕上げて見ます。

本当に有難うございました。

まっさ さん 2004年 05月 20日 11時 32分 51秒

下記のScriptで『Send』フォルダ内の全ファイルを
『receive』フォルダに、経過ダイアログ表示で
コピーしようとしたのですが、下記のように
送り側にワイルドカード指定で記述するとコピーされません。
(直接ファイル名を指定すればOKでした。)
たしかワイルドカードも可能と聞いたのですが
記述の方法が間違っているのでしょうか?
どなたかよろしくお願いいたします(;_;)



*****************************************
Dim RFolder,sFile

'受け側フォルダ
RFolder="D:\receive\"

'送り側ファイル
sFile="D:\Send\*.*"

Set Shell = WScript.CreateObject("Shell.Application")
Set oFolder=Shell.NameSpace(RFolder)
oFolder.CopyHere sFile
MsgBox "完了"
************************************************

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

To: yos さん

> というようなスクリプトを組んでタスクから [実行するファイル名] を
> "C:\tekitou\test.vbs" -a
> と指定して実行してみると、見事に"オプションが指定されてません"

タスクスケジューラでスクリプトを実行させるには、wscript.exeもしくは
cscript.exeを明示してやる必要があるみたいです。

つまり、
wscript.exe C:\tekitou\test.vbs -a
のように登録することになります。
(WinXPの場合)


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

> IEのStatusBarのStatusTextを使ったProgressBar擬

これ、たしかにコンパクトでいい感じです。

私は昔、Shell.Windowsから表示中のフォルダのWindow
オブジェクトを取得し、そのStatusTextにProgressBarもどきを
表示させてみたことがありますが、フォルダが表示されてない場合は
使えませんし、何か無理やり感が漂っていたので実用化を諦めました。

ですが、IEのインスタンスを新しく起動すれば良かったわけですね。

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

IEのStatusBarのStatusTextを使ったProgressBar擬

Set ie=CreateObject("InternetExplorer.Application")
ie.Top = 270:ie.Left = 250:ie.Width = 300:ie.Height = 47
ie.AddressBar = False:ie.MenuBar = False:ie.ToolBar = False
ie.Visible=True

For k=1 To 20
ie.StatusText="(" & k*100 \ 20 & "%)" & String(k,"■")
WScript.Sleep 1000
Next
ie.Quit

結構、コンパクトに作れるので、お勧めかも。

モードレスメッセージボックスとしても使えますね。

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

ScriptControl経由でJScriptからVBScriptを呼び出す。

var SC = new ActiveXObject("ScriptControl");
SC.Language = "VBScript";
//evalを使って、
var s=SC.eval('InputBox("Enter")');
var r=SC.eval('MsgBox("' + s + '")');
var vbOK=SC.eval("vbOK");
WScript.Echo(r,vbOK);
//AddCodeとRunを使って、
SC.AddCode("Function Msg(s):Msg=MsgBox(s):End Function:Function Input(s):Input=InputBox(s):End Function");
var s=SC.Run("Input","Enter");
SC.Run("Msg",s);
//AddCodeとCodeObjectを使って、
var vbs=SC.CodeObject;
s=vbs.Input("Enter");
vbs.Msg(s);

yos さん 2004年 05月 19日 17時 33分 40秒

はじめまして。

Windowsのタスクからオプションを指定してVBスクリプトを
呼び出したいのですが、うまくいきません。

どうもタスクからオプションが渡されていない感じです。
試しに、

---------------------------------------------------------------------'ファイル名:"test.vbs"
If WScript.Arguments.Count = 0 Then
WScript.Echo "オプションが指定されてません"
Else
WScript.Echo "オプションは """ & WScript.Arguments.Item(0) & """"
End If
---------------------------------------------------------------------

というようなスクリプトを組んでタスクから [実行するファイル名] を
"C:\tekitou\test.vbs" -a
と指定して実行してみると、見事に"オプションが指定されてません"
と表示されました。

プロンプトからやショートカットのリンク先に指定しての実行だと
うまくいくのですが、タスクだけがうまくいきません。

原因がお分かりになる方がいらっしゃいましたらどうかご教授ください。
よろしくおねがいします。

魔界の仮面弁士 さん 2004年 05月 19日 17時 32分 35秒

》 kenji さん
> WshNet.MapNetworkDrive """dat_1(i)""", """\\server\dat_2(i)"""
ではなく、
WshNet.MapNetworkDrive dat_1(i), "\\server\" & dat_2(i)
にしてみてください。

kenji さん 2004年 05月 19日 17時 22分 29秒

いりやさん、

早速のお返事ありがとうございました。試させて頂きます。
結果後ほどご報告致します。受領ご報告まで。

Return