いちご さん 2006年 01月 27日 18時 05分 25秒
URL:Windows2000とWindowsXPでechoの表示内容がかわる

お世話になります。
今までASPを使用しておりました。
今回、そのASPからVBSを起動して、
サーバーのフォルダをクライアントのフォルダへコピーする仕組みを作成しました。

そのVBSの中で、処理中にメッセージを表示させたいと思い、Wscript.echo "xxxx"という処理を記述しました。
Windows2000では問題ないのですが、WindowsXPで実行すると、
Wscript.echoの部分がダイアログで表示され、都度「OK」を押さないと進まないという現象で悩んでいます。
どうやら、Windows2000ではRunを実行すると、コマンドプロンプトが起動するのに対し、
WindowsXPはコマンドプロンプトが起動しないのが、原因かと思っています。

あまりよく、WSHがわかっていなく、いろいろ調べているところなのですが、
もしおわかりの方がいらっしゃいましたら、ご指導いただけないでしょうか?
よろしくお願い致します。

処理の詳細は...

main.aspのボタンのクリックで、以下を実行

<SCRIPT LANGUAGE="VBScript">
Sub FuncArchiveLocal()
Set wshShell = CreateObject("WScript.Shell")
wshShell.Run "d:\inetpub\wwwroot\test\test.vbs"
Set wshShell = Nothing
</SCRIPT>

test.vbs
WScript.echo "1.Copy中です。しばらくお待ちください..."
Set fso = CreateObject("Scripting.FileSystemObject")
sLocalFolder = "d:\inetpub\wwwroot\test\"
fso.CopyFolder "\\サーバー名\共有フォルダ名\file", sLocalFolder, True
Set fso = Nothing
WScript.echo "1.Copy終了です。しばらくお待ちください..."
WScript.echo "2.Copy中です。しばらくお待ちください..."
Set fso = CreateObject("Scripting.FileSystemObject")
sLocalFolder = "d:\inetpub\wwwroot\test\"
fso.CopyFolder "\\サーバー名\共有フォルダ名\file", sLocalFolder, True
Set fso = Nothing
WScript.echo "2.Copy終了です。しばらくお待ちください..."

環境
Windows2003サーバー
クライアント;Windows2000 or WindowsXP

管理人むたぐち さん 2006年 01月 27日 17時 00分 40秒

ASPで動作するシンプルなアクセス解析スクリプト : フォーラム : eXperts Connection
http://www.exconn.net/Forums/ShowPost.aspx?PostID=8111

改良版をeXConnのLogParserフォーラムにupしてみました。

安藤@大分 さん (ando@inukai.net) 2006年 01月 26日 18時 56分 07秒

>LogParser2.2+ASPで、IISアクセス解析

さっそく試してみました。
いい感じです。

これなら私にも改造できるかも。
ありがとうございます。

管理人むたぐち さん 2006年 01月 26日 17時 58分 47秒

TO_LOCALTIME(time)

TO_STRING(TO_LOCALTIME(time), 'hh:mm:ss')
の方がいいですね…。

# LogParserいじり中。やっぱりCOMオブジェクトはASP.NETより
# ASPで呼んだ方がラクですね。

管理人むたぐち さん 2006年 01月 26日 17時 34分 43秒

LogParser2.2+ASPで、IISアクセス解析を行うもっとも
シンプルなスクリプトです。
ただログを取ってきて表にするだけですが何かの参考に
なるかもしれないので載せておきます。

<%@ LANGUAGE = VBSCRIPT %>
<html>
<body>
<%

Set oLogQuery = CreateObject("MSUtil.LogQuery")
Set oIISW3CInputFormat = CreateObject("MSUtil.LogQuery.IISW3CInputFormat")

aColumn = Array("date","TO_LOCALTIME(time)","cs-method","cs-uri-stem","cs-uri-query","cs-username", _
"REVERSEDNS(c-ip)","c-ip","cs(User-Agent)","cs(Cookie)","cs(Referer)","sc-status", _
"sc-substatus","sc-win32-status","sc-bytes","cs-bytes","time-taken" )

strQuery = "SELECT " & Join(aColumn,",") & _
" FROM C:\WINDOWS\system32\LogFiles\W3SVC1\ex" & GetDate(Now) & ".log"

Response.Write "<table border=1 style=font-size:9pt>"

Response.Write "<tr>"
For I= 0 To UBound(aColumn)
     Response.Write "<th>" & aColumn(I) & "</th>"
Next
Response.Write "</tr>"

Set oRecordSet = oLogQuery.Execute(strQuery, oIISW3CInputFormat)

DO WHILE NOT oRecordSet.atEnd
     Set oRecord = oRecordSet.getRecord
     Response.Write "<tr>"
     For I= 0 To UBound(aColumn)
          sValue = oRecord.getValue(I)
          If IsNull(sValue) Then sValue="&nbsp;"
          Response.Write "<td>" & sValue & "</td>"
     Next
     Response.Write "</tr>"
     oRecordSet.moveNext
LOOP

oRecordSet.close

Function GetDate(dTime)
     GetDate=FixNumber(Year(dTime)) & FixNumber(Month(dTime)) & FixNumber(Day(dTime))
End Function
Function FixNumber(num)
     FixNumber=Right("0" & CStr(num),2)
End Function

%>
</body>
</html>

ばんのしゃーによかばんた さん 2006年 01月 26日 14時 28分 50秒

>ばんのしゃーによかばんた さん 2006年 01月 23日 17時 59分 16秒
>この場合、以下だけでも十分なようです。

訂正。

普通の、他にIEがいる場合には、十分ですが、
他のウィンドウがforeground lockを持っている場合には駄目。
前述のようにAppActivateが必要です。

――――――――――――――――――――――――――――――――――――――
メッセージボックスがピコピコする問題については、

Set wShell=CreateObject("WScript.Shell")
wShell.AppActivate "メモ帳"
MsgBox "最前面に表示されますがフォーカスは取れません。",vbSystemModal


Set wShell=CreateObject("WScript.Shell")
wShell.AppActivate "メモ帳"
wShell.SendKeys "%{Tab}"
wShell.SendKeys "%{Tab}"
MsgBox "最前面に表示されてフォーカスも当たります。"



なきむし さん 2006年 01月 26日 10時 33分 43秒

>新米MCP さん

お返事有難うございます。

そうでしたか!!
危うく「無い答え」を求めてさすらう所でした(^^;
有難うございます。

新米MCP さん 2006年 01月 26日 08時 29分 42秒

>なきむし さん 2006年 01月 26日 07時 45分 54秒

HTMLやHTAからはWScript直下のプロパティやメソッドは使えませんよ。
WScriptはwscript.exeやcscript.exeを使ったときの機能ですから。

Set WshShell = CreateObject("WScript.Shell")
のようにWshShellは使うことができます。

なきむし さん 2006年 01月 26日 07時 45分 54秒

お初です。宜しくお願いします。

XPのサービスパック2を使っています。
それ以外は素の状態とお考え下さい。

ハイパーテキストから"WScript.〜"オブジェクトが呼び出せません。
短いサンプルで構いませんので、
実働する物のソースを先頭から終了まで、丸ごと挙げて欲しいです。

お願いします。

pai さん 2006年 01月 25日 12時 59分 24秒

管理人さん....m(_._)m
ありがとうございました。
問題解決できました。
この二日間丁寧に教えてくれて
貴重なお時間使わせてもらって
本当に心よりお礼をいいます。
ありがとうございます。
また 何かありましたら
ご教授お願いしたいとおもいますが
よろしくお願いいたします。

pai さん 2006年 01月 25日 10時 09分 24秒

ご返事ありがとうございます。
いろいろ迷惑かけて、ごめんなさい!
問題は下のコードをwindows2000で実行すると
圧縮ファイルを作ってくれますがwindows20003で
実行するとなぜか空の圧縮ファイルが出来上がるんです。
どこかまちがっているとは思いますが
私のレベルが低くてみつかることができませんでした。
完成させたい機能:
指定フォルダ内の指定ファイルをコピーして
他の指定フォルダ内に圧縮させてほぞんしたいです。
どこかにこの機能を完成できるほかの参照用のVBSコードは
ありませんか?
問題のコードです:
Dim fso
Dim wShell
Dim sourceFolderPath
Dim sourceFilePath
Dim targetFolderPath
Dim Shell
Dim ie
Dim file
Dim d
Dim sourceFolder
Dim TargetFolder
Dim sourceFile
Dim zipfile
Dim zip
Dim dFolder
Dim ZIPdata:ZIPdata="PK" & Chr(5) & Chr(6) & String(18,0)

sourceFilePath="C:\job\VBS\新しいフォルダ\test1.txt"
targetFolderPath="C:\job\VBS\zip\"

Set fso=CreateObject("Scripting.FileSystemObject")
Set wShell=CreateObject("WScript.Shell")

'CreateObject("WScript.Shell").Run "explorer.exe",0,True
'WScript.Sleep 100
Set Shell=CreateObject("Shell.Application")
set sourceFile = fso.GetFile(sourceFilePath)
set targetFolder = fso.GetFolder(targetFolderPath)

d = sourceFile.DateLastModified
zipfile=targetFolderPath & Year(d) & Month(d) & Day(d) & sourceFile.Name & ".zip"
fso.CreateTextFile(zipfile).write ZIPdata
Set dFolder=Shell.NameSpace(zipfile)
Set Folder=Shell.NameSpace(sourceFile.ParentFolder.Path)
Set FolderItem=Folder.ParseName(sourceFile.Name)
dFolder.CopyHere FolderItem,&H10

管理人むたぐち さん 2006年 01月 24日 21時 40分 27秒

To: pai さん 2006年 01月 24日 11時 36分 21秒

> 例えば上記の命令を直接Vbsソースの中に入れてやると取得したいイベントログを
> 取ってくれるんですよ。こんな感じに簡単できないかということです。

コードの一部を切り取って別のコードの中に埋め込み
実行することができるかどうか、ということですね。

VBSのコードは基本的には1行目から順に実行されていきますので、
実行させたい部分に埋め込めば原理的には可能です。
ですが、変数の重複など、考慮しなければいけない問題もあります。
ので、コードをそのまま埋め込み可能かどうかは
「場合による」としか言えません。

で、結局あとは何が問題なのでしょうか?

じゃんぬねっと さん 2006年 01月 24日 14時 50分 59秒
URL:http://jeanne.wankuma.com/

母国のコミュニティで投稿なさった方が良いと思います。

pai さん 2006年 01月 24日 13時 00分 21秒

下の質問ですが
消していただけないでしょうか?
ちょっと間違い字を打ったんです。
本当にもうしわけないです。

pai さん 2006年 01月 24日 12時 04分 43秒

下記のそーすがおウィン2000では
動いてくるdんすが2003だと
ろるだが 
なにが知がご存知のかたはぜひおしえてください!
Dim fso
Dim wShell
Dim sourceFolderPath
Dim sourceFilePath
Dim targetFolderPath
Dim Shell
Dim ie
Dim file
Dim d
Dim sourceFolder
Dim TargetFolder
Dim sourceFile
Dim zipfile
Dim zip
Dim dFolder
Dim ZIPdata:ZIPdata="PK" & Chr(5) & Chr(6) & String(18,0)

sourceFilePath="C:\job\VBS\新しいフォルダ\test1.txt"
targetFolderPath="C:\job\VBS\zip\"

Set fso=CreateObject("Scripting.FileSystemObject")
Set wShell=CreateObject("WScript.Shell")

'CreateObject("WScript.Shell").Run "explorer.exe",0,True
'WScript.Sleep 100
Set Shell=CreateObject("Shell.Application")
set sourceFile = fso.GetFile(sourceFilePath)
set targetFolder = fso.GetFolder(targetFolderPath)

d = sourceFile.DateLastModified
zipfile=targetFolderPath & Year(d) & Month(d) & Day(d) & sourceFile.Name & ".zip"
fso.CreateTextFile(zipfile).write ZIPdata
Set dFolder=Shell.NameSpace(zipfile)
Set Folder=Shell.NameSpace(sourceFile.ParentFolder.Path)
Set FolderItem=Folder.ParseName(sourceFile.Name)
dFolder.CopyHere FolderItem,&H10



???助かります。よろしくおねがいいたします。

pai さん 2006年 01月 24日 11時 36分 21秒

管理人さん、ありがとうございます。返事がおそくなりました。
すみません。説明が下手で、やりたいことはこんな感じです。
WshShell.Run "cmd /c eventquery.vbs /S xxxx /fi ""Datetime gt 01/10/2006,02:50:00AM AND ID eq xx"" /fi ""Type eq INFORMATION AND Source eq Print"" /l system /v /fo CSV > c:\Temp1_prlog.txt"
例えば上記の命令を直接Vbsソースの中に入れてやると取得したいイベントログを
取ってくれるんですよ。こんな感じに簡単できないかということです。
これもなんかいまいち下手な気がするけどうまく表現できないです。T。T;

管理人むたぐち さん 2006年 01月 23日 22時 03分 44秒

To: pai さん

> そうですか!やはりXCACLS.Vbsみたい直接Vbsソースの中に埋め込んで
> 使えないですね。わかりました。

ええと、私はできるともできないとも言っていないわけですが…。
いまいちやりたいことが分からないのです。
「直接VBSソースの中に埋め込む」とは具体的にどういうことを
指すのでしょうか?

> 上記のソースを実行させると「上書きしますか??」
> というウィンドウが出てきますが
> 何とか無くせないでしょうか?

これならお答えできます。
dFolder.CopyHere FolderItem,&H10
のように、確認ダイアログ抑制オプションをつけてみては
いかがでしょうか?

pai さん 2006年 01月 23日 19時 28分 11秒

お忙しいところ早速の返事ありがとうございます。
そうですか!やはりXCACLS.Vbsみたい直接Vbsソースの中に埋め込んで
使えないですね。わかりました。

> ここのサイドでコマンドラインで
> 実行させるソースを拝見しましたがそれはフォルダのなかの全部の
> ファイルを一個ずつ 圧縮させたので
すみません、他人のソースを見本で作ってきたんで、
いきなり新規作成といわれて、焦って頭が混乱してしまい
ほかのサイドと勘違いしまいました。
参照したのはここをみて
>VBA さん 2006年 01月 16日 23時 24分 54秒
>吉岡照雄氏が作られた、ZIP.VBSをExcelVBAに移植して圧縮処理を行いたいと思ZIP.VBSをヒントに
さらにインターネットで探したものです。
アドレスはhttp://www.hatena.ne.jp/1123181645でした。
でいまは上記のソースを参考にして
zipファイルが作れるようになりましたが
新たに問題が出てきました。
ソースはこちらです。これを作るにも4時間かかりました。へとへとです。
'C:\job\VBS\新しいフォルダ  にもとのファイルがあり
'C:\job\VBS\zip       に出力するとします。
Dim fso
Dim wShell
Dim sourceFolderPath
Dim sourceFilePath
Dim targetFolderPath
Dim Shell
Dim ie
Dim file
Dim d
Dim sourceFolder
Dim TargetFolder
Dim sourceFile
Dim zipfile
Dim zip
Dim dFolder
Dim ZIPdata:ZIPdata="PK" & Chr(5) & Chr(6) & String(18,0)

sourceFilePath="C:\job\VBS\新しいフォルダ\test1.txt"
targetFolderPath="C:\job\VBS\zip\"

Set fso=CreateObject("Scripting.FileSystemObject")
Set wShell=CreateObject("WScript.Shell")

'CreateObject("WScript.Shell").Run "explorer.exe",0,True
'WScript.Sleep 100
Set Shell=CreateObject("Shell.Application")
set sourceFile = fso.GetFile(sourceFilePath)
set targetFolder = fso.GetFolder(targetFolderPath)

d = sourceFile.DateLastModified
zipfile=targetFolderPath & Year(d) & Month(d) & Day(d) & sourceFile.Name & ".zip"
fso.CreateTextFile(zipfile).write ZIPdata
Set dFolder=Shell.NameSpace(zipfile)
Set Folder=Shell.NameSpace(sourceFile.ParentFolder.Path)
Set FolderItem=Folder.ParseName(sourceFile.Name)
dFolder.CopyHere FolderItem
上記のソースを実行させると「上書きしますか??」
というウィンドウが出てきますが
何とか無くせないでしょうか?
私がいま実行させたい機能はこれをある時間帯にバッチファイルから
呼び出され、実行するXXX.Vbsソースのなかに埋め込みたいですので
このメッセジーがずっと出てくると....T.T;
なんとかしてなくしたいですがいい方法はありませんか?
ぜひともよろしくお願いいたします。

管理人むたぐち さん 2006年 01月 23日 18時 41分 00秒

To: pai(初心者です。) さん

> windows2003でマウスの右クリックで圧縮を実行できますが

これは何らかのソフトを入れてないと無理なのでは?
もしくは「プロパティ」から設定できる圧縮属性のことでしょうか?

> ここのサイドでコマンドラインで
> 実行させるソースを拝見しましたがそれはフォルダのなかの全部の
> ファイルを一個ずつ 圧縮させたので

これ、どれのことでしょうか? アドレスを教えてください。

ばんのしゃーによかばんた さん 2006年 01月 23日 17時 59分 16秒

「新規作成」の利用法です。

.VBSの「新規作成」が空いているので、今回はそれを活用します。
HKCR\.VBS\ShellNew\commandに、WScript.exe フルパス.VBS "%1"と入れると、
「新規作成」に「VBScript Script File」が追加されます。(再ログオン要)
クリックすると、%1に、フォルダ\新規VBScript Script File.vbs
が渡ってきます。
エクスプローラだけでなく「ファイルを開く」や「名前を付けて保存」でも、
「新規作成」が使えるので、そのフォルダをパラメタにした処理が起動できます。

%2!d! でなにやら数字が渡ってきますが、エクスプローラの
ウィンドウハンドルのようです。

ダミーの拡張子とファイルタイプを作ってやれば、「新規作成」メニューの
タイトルを好きに変えられます。

――――――――――――――――――――――――――――――――――――――
>ばんのしゃーによかばんた さん 2006年 01月 21日 15時 11分 38秒
>IEウィンドウ隠れ防止対策.VBS

この場合、以下だけでも十分なようです。

ie.Visible=True
If Not ie.Document.hasFocus Then
wShell.SendKeys "%{Tab}"
End If


pai(初心者です。) さん 2006年 01月 23日 15時 11分 59秒

ファイルの圧縮に関する質問です。
windows2003でマウスの右クリックで圧縮を実行できますが
XCACLS.vbs...xcopy.vbs みたいに直接vbscriptの中で命令で
実行させることは可能ですか?ここのサイドでコマンドラインで
実行させるソースを拝見しましたがそれはフォルダのなかの全部の
ファイルを一個ずつ 圧縮させたので これを改良すれば
指定ファイルのみ圧縮させることは可能ですか?
お忙しいと思いながらVBS初心者で、自分で解決できなかったので
教えていただけますか?よろしくお願いいたします.

管理人むたぐち さん 2006年 01月 23日 10時 09分 31秒

To: mさん

InputBox関数はVBScriptにもありますよ。
JScriptには同等のものはありませんが…。
詳しくはWSHのヘルプをご覧ください。

m さん 2006年 01月 23日 00時 02分 25秒

初めまして、mと申します。

WSHを使って便利だなあと思いながらコードを書いていたのですが・・・
VBでいう「inputbox」(関数)ってどうやって表示させるのだろうと思いました。
アドバイスよろしくお願いします。

ばんのしゃーによかばんた さん 2006年 01月 21日 15時 11分 38秒

>ばんのしゃーによかばんた さん 2005年 12月 26日 16時 36分 59秒

>ばんのしゃーによかばんた さん 2005年 12月 27日 14時 43分 03秒
では、
IEのウィンドウが前面に出るケースと後面に隠れるケースがあります。

条件が分からず、何でかなぁと思っていたのですが、
IEの場合、
>ばんのしゃーによかばんた さん 2005年 02月 02日 16時 24分 30秒
こういうことがあるので、試してみますと、
他にIEがなければ前面に出ますが、あると背後に隠れます。
こういうことだったのですね。

そこで、と言っても、他にIEがあるのは避け難いので、
隠れたことを検出して、隠れていたら前面に引っ張り出します。

IEウィンドウ隠れ防止対策.VBS
――――――――――――――――――――――――――――――――――――――
Set wShell=CreateObject("WScript.Shell")
Set ie=CreateObject("InternetExplorer.Application")
ie.Navigate "about:blank"
Do While ie.Busy Or ie.ReadyState<>4
 WScript.Sleep 100
Loop
ie.Visible=True
If Not ie.Document.hasFocus Then
 Title=ie.Document.Title
 ie.Document.Title="hogehoge"&ie.hwnd
 wShell.SendKeys "%{Tab}"
 WScript.Sleep 100
 wShell.AppActivate ie.Document.Title
 ie.Document.Title=Title
End If
――――――――――――――――――――――――――――――――――――――
それから、この防止対策は、このIEの問題にだけでなく、序でに、
あのForegroundFlash問題にも、耐えられるようにしてみました。

一般のForegroundFlash(LockSetForegroundWindow)問題について言及すると、
Alt+TabするとForegroundLockが外れるようです。

AppActivate点滅防止対策.VBS
――――――――――――――――――――――――――――――――――――――
Set wShell=CreateObject("WScript.Shell")
wShell.SendKeys "%{Tab}"
WScript.Sleep 100
wShell.AppActivate "タイトル"
'wShell.SendKeys "%( r)"     '最小化対策
――――――――――――――――――――――――――――――――――――――


ちゃっぴ さん 2006年 01月 21日 11時 45分 00秒

To さんぽす さん 2006年 01月 20日 19時 44分 04秒

Oracle に INSERT するのであれば、SQLPlus を使用せずとも、
ADO とか OO4o とかで INSERT すればいいと思いますがね。

AKA さん 2006年 01月 21日 06時 57分 22秒

WIN32API.EXEに「一番最後のパラメータの解釈が変になる」バグがあったので、修正しました。

http://winscript.s41.xrea.com/wiki/index.php?plugin=attach&pcmd=open&file=W32E002.LZH&refer=%5B%5B%A5%A2%A5%C3%A5%D7%A5%ED%A1%BC%A5%C0%A1%BC%5D%5D

WIN32API.EXEの使用例。

常駐してNumLockキーの状態を監視し、状態が変化したら終了します。監視は1秒ごとに行います。

'<<WAITNUM.VBS>>

Set ws = CreateObject("WScript.Shell")
NumLockStateOld = ws.Run("WIN32API USER32 GetKeyState l 144", 0, True)
Do While True
     WScript.Sleep 1000
     NumLockState = ws.Run("WIN32API USER32 GetKeyState l 144", 0, True)
     If NumLockState <> NumLockStateOld Then
          Exit Do
    End If
Loop
MsgBox "Num Lock Changed"


おまけのジョーク。

'<<BEEPLAY.VBS>>

' For WinNT Only

Set ws = CreateObject("WScript.Shell")

ws.Run "WIN32API KERNEL32 Beep ll 1056 160", , True
ws.Run "WIN32API KERNEL32 Sleep l 160", , True
ws.Run "WIN32API KERNEL32 Beep ll 784 160", , True
ws.Run "WIN32API KERNEL32 Beep ll 784 160", , True
ws.Run "WIN32API KERNEL32 Beep ll 816 320", , True
ws.Run "WIN32API KERNEL32 Beep ll 784 160", , True
ws.Run "WIN32API KERNEL32 Sleep l 600", , True
ws.Run "WIN32API KERNEL32 Beep ll 992 160", , True
ws.Run "WIN32API KERNEL32 Sleep l 160", , True
ws.Run "WIN32API KERNEL32 Beep ll 1056 160", , True

>>管理人さん
どうも。なるほど。考えて見ます。でもおこられるかも・・・

管理人むたぐち さん 2006年 01月 20日 21時 40分 34秒

To: さんぽす さん

要は標準入力にコマンドを与えてやればいいわけです。
WSHには標準入出力を制御する方法が提供されています。
詳しくはExec メソッド、StdOut プロパティ (WshScriptExec)
などをヘルプで調べてみてください。

また、Googleで"sqlplus wsh"を検索するとサンプルが見つかりました。
これも参考になるのでは?

http://otn.oracle.co.jp/cgi-bin/non/msgview_r.cgi?communityid=otn-489965&bbsid=1&no=52080&view=8

さんぽす さん 2006年 01月 20日 19時 44分 04秒

何かいい方法がありませんでしょうか?

wshでVBScriptを動かし、
VBScriptのループ内でsqlplusを使用してinsertを繰り返し行いたいとします。

まずVBScriptの始めに
Dim WSHShell
Set WSHShell = WScript.CreateObject("WScript.Shell")
WSHShell.Run "sqlplus aaa/bbb@dbname"
を行い、sqlplusを起動、DBコネクトを行います。
その後、sqlplusに対して、コマンド(insert文)を実行させたいのですが、
やり方がわかりません。

ばんのしゃーによかばんた さん 2006年 01月 20日 16時 37分 23秒

>ばんのしゃーによかばんた さん 2006年 01月 17日 14時 52分 18秒
>ところで、この検索の機能はスクリプトから何とか使えないものでしょうかねぇ。
>今のところ、手も足も出ません。。。

「検索条件を保存」した.FNDファイルの構造の解説が何処かにありません?
もし、それが分かれば、スクリプトで.FNDファイルを生成して、キックしてやれば、
少なくともバッチ処理的にはスクリプトから使えるようになるんですが。。。


ばんのしゃーによかばんた さん 2006年 01月 20日 16時 37分 02秒

>ばんのしゃーによかばんた さん 2006年 01月 18日 14時 40分 27秒
>FolderItem.InvokeVerb "ショートカットの作成(&S)"

これは、
FolderItem.InvokeVerb "link"
でもよいようです。

"pastelink"というVerbが"ショートカットの貼り付け(&S)"に対応している
と思うのですが、これらはどうやって使うのか分かりません。
これらのVerbは、folder backgroundのVerbのようですが、
そもそもfolder backgroundを扱うにはどうすればよいのでしょう?

あと、ショートカットを全く新規に作成する場合、WScript.Shellでないと
出来ない。ということはなく、FSOで空の.lnkを作って、
後はそれをShell.Applicationで掴んで、設定してやればよいようです。

ただ、そうやっても、デスクトップディレクトリのショートカットの場合は、
WScript.Shellで作ったのと同じで、仮想フォルダになってしまいます。

デスクトップの実ディレクトリへのショートカットは、InvokeVerbで作れますが、
この違いが何なのか、調べてみたいのですが、.LNKファイルの構造の解説は
何処かにありません?

話変わって、ショートカット話の序でに、
「フォルダのショートカット」はスタートメニューやツールバー限定の
機能のようで、その他一般(Sndtoなど)には使わないほうがよさそうです。
リンクにSendTo、SendToにリンク、の「フォルダのショートカット」を置くと、
エクスプローラが無限ループから抜け出せなくなります。ご用心。
スタートメニューやツールバーで使っている分には、無限ループ抑制機能が
働くようです。


はてなぁ さん 2006年 01月 19日 15時 57分 15秒

To:むたぐちさん

なるほど・・・。
WSHとは関係ないのにありがとうございました。

管理人むたぐち さん 2006年 01月 19日 15時 33分 30秒

To: はてなぁ さん

それはIEで動作するExcelのActiveXドキュメントにFTP or WebDAV
アップロードの機能がないのに加え、AN HTTPDにFTP or WebDAV
サーバーの機能がないためだと思われます。

サーバーは対応のものを新たに導入することで対処できますが、
クライアント側はどうしようもない気がします。

はてなぁ さん 2006年 01月 19日 15時 27分 12秒

To:むたぐちさん

説明が足りなくて申し訳ありません

環境はWin2000 Office2000 です
AN HTTPD ver1.42 でサーバーを立てています。
グループ内でIEを使ってファイルの共有をしたいと考えています。
ブラウザ上でエクセルファイルを開いて、そこにデータを入れ上書き保存する
ような感じでやりたいと思っています。

IEで直接開いてもいいし、別途エクセルを立ち上げてでもいいのですが・・・。

マイコンピュータから直接エクセルファイルをIEで開くと上書き保存できるのですがネットワーク上(IEのアドレスにhttp://192.・・・・・・)といれて開くと
上書き保存できなくなります(名前を付けて保存はできますが)

なんか・・・WSHの質問ではなくなってきてる気が・・・
当初はWSHで直接エクセル立ち上げれば上書き保存ができるのかと思って試行錯誤
していたので。

管理人むたぐち さん 2006年 01月 19日 14時 01分 59秒

To: はてなぁ さん

> ブラウザからエクセルを起動し、ファイルを開くまではできたのですが、開くファイルが読み取り専用になってしまいます。
> もともとのエクセルファイルは読み取り専用ではありません。

環境はどのような感じでしょうか?

当方の環境(WindowsXP Pro + Office 2003)では再現しませんでした。
というかhtmlではセキュリティ機構が働いて動作しなかったので、
htaにして動作させましたが、そのあたりも含めて詳しい環境を
お教えください。

管理人むたぐち さん 2006年 01月 19日 13時 51分 08秒

To: VBA さん

> どこかに(例えばMSDNに)、仕様は明記されていませんでしょうか?
> (意味を正確に理解したいと思っています。)

WinZIPのサイトに仕様書がありました。
http://www.winzip.com/aes_info.htm#zip-format

> 下の部分ですが、Shellオブジェクトを呼び出していると思うのですが、
> ie.Document.Applicationとはどういう意味でしょうか?

Set Shell=CreateObject("Shell.Application")
と等価なのではないでしょうか?(自信なし)
Applicationメソッドは、folder.httでShellオブジェクトを
呼ぶときに使われていたと思います。
FileList.Folder.Applicationのように。
MSDNはこちら。
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/objects/folder/application.asp



To: scotchegg さん

> 先日Class ステートメントの使い方について話が出ていましたが、可変長
> 配列クラスの実装例を上記ページで、奇遇にも先日公開したところでした。

ありがとうございます。Classの組み立て方から書かれていて非常に参考になります。
私が作ったやつよりかなりいい感じですね。Removeもちゃんとできますし…。

管理人むたぐち さん 2006年 01月 19日 13時 32分 10秒

To: ごおお さん

> 具体的にはあるサイトにログインし、その先のHTMLをファイルに出力という操作を行っています。

InternetExplorer.Applicationに問題があるようなら、Msxml2.XMLHTTPを使って
POSTを行ってはいかがでしょうか。

sSource = "http://..."
sDest = "Output.txt"
Const adTypeBinary = 1
Const adSaveCreateNotExist = 1
Const adSaveCreateOverWrite = 2
Set oHTTP = WScript.CreateObject("Msxml2.XMLHTTP")
oHTTP.Open "POST", sSource, False
oHTTP.Send ("login=*****" & _
   "&passwd=****")
Set Stream = WScript.CreateObject("Adodb.Stream")
Stream.Type = adTypeBinary
Stream.Open
Stream.Write oHTTP.responseBody
Stream.Savetofile sDest, adSaveCreateOverWrite

もし、ログイン名やユーザー名に日本語の文字が含まれる場合は、
 oHTTP.Send ("login=" & UrlEncode("*****") & _
   "&passwd=" & UrlEncode("****")
のようにしてUrlエンコードを行ってください。UrlEncode関数は
Wikiにあります。
http://winscript.s41.xrea.com/wiki/index.php?%5B%5B%A5%C6%A5%AF%A5%CB%A5%C3%A5%AF%5D%5D#content_1_5

はてなぁ さん 2006年 01月 18日 16時 53分 52秒

初心者です

IEでホームページを作っていて、ブラウザからエクセルを起動して、エクセルファイルを開いてデータを保存したいと思っています。

ブラウザからエクセルを起動し、ファイルを開くまではできたのですが、開くファイルが読み取り専用になってしまいます。
もともとのエクセルファイルは読み取り専用ではありません。

いろいろwebで調べてみたのですがわかりません。
どなたかアドバイスお願いできませんでしょうか?

<script language="JavaScript">
function excel(){
  wshshell=new ActiveXObject("WScript.Shell")
  wshshell.run("test.xls")
}
</script>

ばんのしゃーによかばんた さん 2006年 01月 18日 14時 40分 27秒

ショートカット作成スクリプトシリーズ(?)の第4段です。

デスクトップのショートカットは、普通に作ると、仮想フォルダのデスクトップ
になって、実ディレクトリのデスクトップになってくれません。
実デスクトップのショートカットは、やっとさ作っても、不安定なようで、
プロパティをちょっといじると仮想デスクトップになってしまいます。

仮想デスクトップ.VBS
――――――――――――――――――――――――――――――――――――――
Set wShell=CreateObject("WScript.Shell")
Set Link=wShell.CreateShortCut("デスクトップ フォルダ.lnk")
Link.TargetPath="shell:desktopfolder"
Link.Description="デスクトップ フォルダ"
Link.Save
――――――――――――――――――――――――――――――――――――――

実デスクトップ.VBS
――――――――――――――――――――――――――――――――――――――
Path=WScript.ScriptFullName
FolderName=Left(Path,InStrRev(Path,"\"))
FileName="デスクトップ へのショートカット.lnk"
Set Shell=CreateObject("Shell.Application")
Set Folder=Shell.NameSpace(16)
Set FolderItem=Folder.Items().item()
FolderItem.InvokeVerb "ショートカットの作成(&S)"
Set FolderItem=Folder.ParentFolder.Items().item(FileName)
Set Folder=Shell.NameSpace(FolderName)
Folder.MoveHere FolderItem
Set FolderItem=Folder.ParseName(FileName)
Set Link=FolderItem.GetLink
Link.Description="デスクトップ ディレクトリ"
Link.Save
――――――――――――――――――――――――――――――――――――――


ばんのしゃーによかばんた さん 2006年 01月 17日 14時 52分 18秒

ショートカット作成スクリプトシリーズ(?)の第3段です。

「ファイルやフォルダの検索」のショートカット「検索(C).lnk」を作ります。
――――――――――――――――――――――――――――――――――――――
Set wShell=CreateObject("WScript.Shell")
Set Link=wShell.CreateShortCut("検索(C).lnk")
Link.TargetPath="shell:::{2559a1f0-21d7-11d4-bdaf-00c04f60b9f0}"
Link.Description="検索(C)"
Link.Save
――――――――――――――――――――――――――――――――――――――
因みに、これも、記憶力とタイピングに自信のあるひとは、アドレスバーに、
shell:::{2559a1f0-21d7-11d4-bdaf-00c04f60b9f0}
と入れれば、検索バーが開きますが、態々そうすることもないか。。。

ところで、この検索の機能はスクリプトから何とか使えないものでしょうかねぇ。
今のところ、手も足も出ません。。。

>ばんのしゃーによかばんた さん 2006年 01月 16日 16時 26分 09秒
>「ファイル名を指定して実行」ダイアログのショートカット「ファイル名を指定して実行.lnk」を作ります。

これもこっちが簡単でした。
――――――――――――――――――――――――――――――――――――――
Set wShell=CreateObject("WScript.Shell")
Set Link=wShell.CreateShortCut("ファイル名を指定して実行(R)....lnk")
Link.TargetPath="shell:::{2559a1f3-21d7-11d4-bdaf-00c04f60b9f0}"
Link.Description="ファイル名を指定して実行(R)..."
Link.Save
――――――――――――――――――――――――――――――――――――――

>「ファイル名を指定して実行」ダイアログにはファイルをドロップできます。

補足。

もし、客先などのシステムで、
Windows PowerToyのSend To Clipboard as Name.NameOnClipboard
があったらなぁ、なんてときは、「ファイル名を指定して実行」ダイアログを
思い出しましょう。代わりに使えます。

「ファイル名を指定して実行」ダイアログにファイル(複数可)をドロップして
パス名の並びをCTRL+Cでコピーします。


ごおお さん 2006年 01月 17日 11時 14分 32秒

むたぐちさん

返信ありがとうございます&返信遅くなってすみません
>IE.Visible = Trueという行でIEのウィンドウを可視化してると思いますが、
>これを省略して、非表示のまま実行させてはいかがでしょうか?

ウィンドウの可視化は行っていないのですが、フォーカスが移ってしまいます。
正確には新しく作ったIEにフォーカスが移ったかどうかは確認できないのですが、その時操作しているウィンドウがスクリプト中でIEを閉じるまでフォーカスを失い操作できなくなってしまいます。なにかいい方法はないでしょうか?

具体的にはあるサイトにログインし、その先のHTMLをファイルに出力という操作を行っています。

もしなにかいい方法をご存知でしたらご教授ください。
よろしくお願いします。

  Dim objIE 'IEオブジェクト参照用

  'インターネットエクスプローラーのオブジェクトを作る
  Set objIE = CreateObject("InternetExplorer.application")
  
  'オフラインに
  objIE.Offline = true
  'ログインページに飛ぶ
  objIE.Navigate LoginURL

  '表示終了まで待つ
   Do While objIE.Busy = True
   Loop
   Do While objIE.readyState <> "4"
   Loop

   'ユーザー名、パスワードをセットする
   objIE.document.all.login.Value = "*****" 'ユーザー名
   objIE.document.all.passwd.Value = "****"  'パスワード
  
   objIE.Offline = false
   'データせっとできたので、Submit
   objIE.document.forms(0).Submit
  
   'ビジー、読み込み中の間待機
   Do While objIE.Busy = True
   Loop
   Do While objIE.readyState <> "4"
   Loop
  
  objIE.Navigate GetURL
  
  'ビジー、読み込み中の間待機
  Do While objIE.Busy = True  'ビジー、読み込み中の間
  Loop
  Do While objIE.readyState <> "4"
   Loop
  
  'HTMLソースを取出す
  ReturnedData = objIE.Document.body.innerHTML
  
  'HTMLソースを出力
     call OutputText(DebugPath + "Output.txt", ReturnedData)
    
     'IEを閉じる
     objIE.quit

scotchegg さん 2006年 01月 17日 08時 46分 05秒
URL:http://www012.upp.so-net.ne.jp/scotchegg/VBScript/Vector.htm

はじめまして。

先日Class ステートメントの使い方について話が出ていましたが、可変長
配列クラスの実装例を上記ページで、奇遇にも先日公開したところでした。
良かったらご覧ください。

VBA さん 2006年 01月 16日 23時 24分 54秒

吉岡照雄氏が作られた、ZIP.VBSをExcelVBAに移植して圧縮処理を行いたいと思っておりますが、
コードの中で不明な点がいくつかあり、
いろいろ探しましたが、ついに分からなかったので、
質問させて下さい。

ZIP.VBS
http://www.vector.co.jp/soft/winnt/util/se355605.html

1.空のZIPファイルを作成する時に、

Dim ZIPdata:ZIPdata="PK" & Chr(5) & Chr(6) & String(18,0)
fso.CreateTextFile(ZIPfile,False).Write ZIPdata

としていますが、ZIPdata="PK" & Chr(5) & Chr(6) & String(18,0)は、
圧縮ファイルの形式を表すものだと思いますが、
どこかに(例えばMSDNに)、仕様は明記されていませんでしょうか?
(意味を正確に理解したいと思っています。)

2.Shell=ie.Document.Applicationについて

下の部分ですが、Shellオブジェクトを呼び出していると思うのですが、
ie.Document.Applicationとはどういう意味でしょうか?

リファレンス等を見たいのですが、見つけられませんでした。

------------
Set ie=CreateObject("InternetExplorer.Application")
...
Set Shell=ie.Document.Application
------------

すみませんが、ご教授頂けたらと思います。

ばんのしゃーによかばんた さん 2006年 01月 16日 16時 26分 09秒

ショートカット作成スクリプトシリーズ(?)の第2段です。

「ファイル名を指定して実行」ダイアログのショートカット「ファイル名を指定して実行.lnk」を作ります。

ファイル名を指定して実行.WSF
――――――――――――――――――――――――――――――――――――――
<package>
<job>
<script language="VBScript">
Option Explicit
Const adTypeBinary=1
Dim dFile
Dim Dom
Dim Tmp
Dim Bin
Dim Dst
If WScript.Arguments.Count=1 Then
 dFile=WScript.Arguments.Item(0)
Else
 dFile=Left(WScript.ScriptFullName,InStrRev(WScript.ScriptFullName,"\"))&getResource("filename")
End If
Set Dom=CreateObject("Microsoft.XMLDOM")
Set Tmp=Dom.createElement("tmp")
Tmp.DataType="bin.base64"
Tmp.Text=getResource("base64")
Bin=Tmp.NodeTypedValue
Set Dst=CreateObject("ADODB.Stream")
Dst.Open
Dst.Type=adTypeBinary
Dst.Write Bin
Dst.SaveToFile dFile
Dst.Close
</script>
<resource id="filename">ファイル名を指定して実行.lnk</resource>
<resource id="base64">
TAAAAAEUAgAAAAAAwAAAAAAAAEaFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAQAAAAAAAAAAAAAAAAAAABYAFAAfgPOhWSXXIdQRva8AwE9gufAAABMA1TChMKQw
6zANVJIwB2OaW1cwZjCfW0yIKAAmAFIAKQAuAC4ALgAAAAAA
</resource>
</job>
</package>
――――――――――――――――――――――――――――――――――――――
※なんか、無理矢理、WSH/スクリプティング話にしている感もありますが。。。

因みに、記憶力とタイピングに自信のあるひとは、アドレスバーに、
shell:::{2559a1f3-21d7-11d4-bdaf-00c04f60b9f0}
と入れても、「ファイル名を指定して実行」ダイアログが開きます。

ところで、ちょっと脱線気味ですが、
「ファイル名を指定して実行」ダイアログにはファイルをドロップできます。
XPでVerbのレジストリ定義にDropTargetキーが追加されています。
これを利用して、Windows PowerToyのSend To Command Line.CommandLine
みたいなことが定義の追加だけで出来たりしないものでしょうか?


ばんのしゃーによかばんた さん 2006年 01月 15日 15時 30分 29秒

>ばんのしゃーによかばんた さん 2005年 08月 09日 18時 41分 55秒
の改版なのですが、そのままだと、HTA/スクリプティング話になってしまうので、
WSH/スクリプティング話に仕立ててます。

フォルダウィンドウに、親フォルダに移動する「..」を追加するVBScriptです。

UpFolder.VBS
――――――――――――――――――――――――――――――――――――――
Set wShell=CreateObject("WScript.Shell")
Set Link=wShell.CreateShortCut("...LNK")
Link.TargetPath="MSHTA.EXE"
Link.Arguments="vbscript:Execute(""Set ie=CreateObject(""""Shell.Application"""").Windows().Item():ie.Document.Folder.ParentFolder.Items().Item().InvokeVerb """"Explore"""":close"")"
Link.IconLocation="shell32.dll,146"
Link.Description="上へ"
Link.Save
――――――――――――――――――――――――――――――――――――――
ところで、この「..」を、Explorer.exe /root,フォルダ で開いたルートフォルダで
実行すると、親フォルダが別に2つ開きます。
ひとつ開く分には「仕様」ですが、2つも開くのは「障害」です。
これが旧版のNavigateだと、加えて、「不明な例外」「未定義のエラー」が発生します。
同様に、例えば、Explorer.exe /root,フォルダ で開いたエクスプローラで、
お気に入りバーや履歴バーからHTMLのショートカットをクリックすると、
これも、IEのウィンドウが2つ開くので、「一般的な」「障害」のようです。
/rootを使うとき、スクリプトから既存のエクスプローラを制御するときは、要注意です。
スクリプトから事前に判断できればよいのですが、そのためにWMIでコマンドラインを
調べるというのもちょっとね。


ばんのしゃーによかばんた さん 2006年 01月 15日 15時 30分 11秒

CABのGUI強化策の第4弾です。

CABファイル内のファイルがCABファイル外の親フォルダ内のファイルと比べて、
サイズと更新日時に違いがあるかどうかを調べます。
――――――――――――――――――――――――――――――――――――――
Option Explicit
Dim fso
Dim Shell
Dim CABfile
Dim cFolder
Dim cFolderItem
Dim xFolder
Dim xFolderItem
Dim Rows
Dim FileName

If WScript.Arguments.Count<>1 Then
 WScript.Echo "No Arguments !"
 WScript.Quit
End If
CABfile=WScript.Arguments.Item(0)

Set fso=CreateObject("Scripting.FileSystemObject")
Set Shell=CreateObject("Shell.Application")
CABfile=fso.GetAbsolutePathName(CABfile)
If UCase(fso.GetExtensionName(CABfile))<>"CAB" Then
 WScript.Echo "Invalid Extension Name -",fso.GetExtensionName(CABfile)
 WScript.Quit
End If
Set cFolder=Shell.NameSpace(CABfile)
Set xFolder=cFolder.ParentFolder
Rows=Array("Size     ModifyDate     Name")
For Each cFolderItem In cFolder.Items()
 FileName=fso.GetFileName(cFolderItem.Path)
 Set xFolderItem=xFolder.ParseName(FileName)
 If xFolderItem Is Nothing Then
  Push Rows,Join(Array(cFolderItem.ExtendedProperty("Size"),cFolder.GetDetailsOf(cFolderItem,3),FileName),vbTab)
 Else
  If CLng(cFolderItem.ExtendedProperty("Size"))<>xFolderItem.Size Or cFolder.GetDetailsOf(cFolderItem,3)<>xFolder.GetDetailsOf(xFolderItem,3) Then
   Push Rows,Join(Array(cFolderItem.ExtendedProperty("Size"),cFolder.GetDetailsOf(cFolderItem,3),FileName),vbTab)
   Push Rows,Join(Array(xFolderItem.Size,xFolder.GetDetailsOf(xFolderItem,3)),vbTab)
  End If
 End If
Next
If UBound(Rows) Then
 WScript.Echo Join(Rows,vbLf)
Else
 WScript.Echo fso.GetFileName(CABfile)&" is fresh."
End If
WScript.Quit

Sub Push(Items,Item)
ReDim Preserve Items(UBound(Items)+1)
Items(UBound(Items))=Item
End Sub
――――――――――――――――――――――――――――――――――――――
ところで、ZIPは大小文字の違う同名ファイルでエラーになってましたが、
CABは同名ファイルでも置換されずに、複数入るんですね。
その関係で、ParseName(Name)やItems().Item(Name)が使えないのかも。


管理人むたぐち さん 2006年 01月 15日 13時 02分 24秒

To: AKA さん

ご指摘どうもです。

> この場合スクリプトレベル変数で
> >Set oItem = oItems.Add(New CollectionItem) '新しいCollectionItemを> 生成して追加
> としているので見事に当たってます。(^^;)

これ、某所でも指摘されたのですが、変数名をクラス名と一緒にしたり
いろいろと問題ありでした。

ですが書き直すには、
> というかこれ、Classの例としてはあんまり適当じゃないですね。
> 仕様も変・・・
なので練り直すまで少し保留とさせていただきます。

>Wikiのアップローダなのですが、作者の一行コメントがファイル名の隣に並ぶリスト状の表示形式にできないでしょうか?&nbsp;我ながら何のファイルだかわかりにくくて・・・(^^;)

お返事が遅くなりましたが、せっかくのWikiなので
DW専用あるいはAKAさんのアーカイブ専用のページを
作ってはいかがでしょうか?
アップローダの仕様上、リスト状の表示にするのは難しいので
一から表を書くということで…。お手数をおかけします。

AKA さん 2006年 01月 14日 15時 38分 37秒

>>管理人むたぐち さん 2006年 01月 13日 23時 22分 04秒
>●DictionaryオブジェクトとClassステートメントを用いた
> コレクションクラスもどきのテンプレート

45行目他いろいろミスってるようですが(^^;)、

>        Set oItem = CollectionItem
>     Else
>        'ほかの引数なら、新しくCollectionItemクラスのインスタンスを作成
>        Set oItem = New CollectionItem

この場合スクリプトレベル変数で
>Set oItem = oItems.Add(New CollectionItem) '新しいCollectionItemを生成して追加
としているので見事に当たってます。(^^;)


>Set oItems(0) = New CollectionItem '新しいCollectionItemを生成してItemプロパティに代入
>'(↑これはSet oItem(0).Item = New CollectionItemと等価)

「Set oItems.Item(0) = と等価」では?


というかこれ、Classの例としてはあんまり適当じゃないですね。

仕様も変・・・

OOP言語が流行っているので、ちまたにクラスがあふれていますが、クラスを設計するのは実際かなり難しい事です。C++でも「できるのだが、やらない方がいいこと」というのがたくさん定められています。デフォルトプロパティは非常に面白いものですが、混乱の元なので例として使うには気をつけた方がいいと思います。

それと、

>>AKA さん 2005年 12月 31日 07時 34分 58秒
> >>管理人さん
>Wikiのアップローダなのですが、作者の一行コメントがファイル名の隣に並ぶリスト状の表示形式にできないでしょうか?&nbsp;我ながら何のファイルだかわかりにくくて・・・(^^;)

お願いしますよ〜。できないならできないでいいので何か答えてくれ〜。

AKA さん 2006年 01月 14日 06時 34分 21秒

よく、会社のコンピュータなので勝手にコンポーネントを追加できない、というのを目にしますね。

するとDW7もインストールできないですね・・・残念・・・

そこで試しにこんなのを作ってみました。

WIN32API.EXE
http://winscript.s41.xrea.com/wiki/index.php?plugin=attach&pcmd=open&file=W32E001.LZH&refer=%5B%5B%A5%A2%A5%C3%A5%D7%A5%ED%A1%BC%A5%C0%A1%BC%5D%5D

RUNDLLでこういうことができたらよかったのに・・・

というか、こういうの、どっかにあるんじゃないの!?

昔、DOSではファンクションコールで確かにこういうのがありました。PC-9801でもグラフィックLIOを呼び出すコマンドラインツールがあったりしました。(これはテキストとグラフィック画面が完全並立している98ならでは)(つか最近秀和の98解析マニュアル0巻入手。なつかし)

これと同じようなものをご存じの方、どうかお教え下さい。

あと、感想、批評もよろしく! 捨てハンでいいので。

管理人むたぐち さん 2006年 01月 13日 23時 22分 04秒

●DictionaryオブジェクトとClassステートメントを用いた
 コレクションクラスもどきのテンプレート

Classステートメントはいまいち使いどころが分からなかったのですが、
オブジェクト指向を勉強しだすと、徐々にその威力が分かりだしてきました。

以前、
 管理人むたぐち さん 2003年 06月 16日 21時 07分 10秒
 http://www.roy.hi-ho.ne.jp/mutaguchi/bbs/list84.shtml
 管理人むたぐち さん 2003年 07月 01日 17時 59分 07秒
 http://wwwroy.hi-ho.ne.jp/mutaguchi/bbs/list86.shtml
で、Classステートメントの使い方を述べましたが、今回はその応用編として、
Dictionaryオブジェクトを併用して、コレクションクラスもどきを
作ってみたので紹介します。
(以前紹介したclsCollection http://aspzone.com/articles/160.aspx
とはまた少し違ったアプローチで作りました)

これは必要最低限の部分しか記述していないので、実際に用いるときの
テンプレートとして使えます。

というか、そもそもWSHのヘルプだけではClassステートメントの使い方を理解するのは
困難だと思われますので、こういう実例を見て勉強したほうが
理解が早いと思います。


Class CollectionItem
'クラスCollectionItem。要素を表す
     Private m_sProperty1 'プロパティProperty1の値を格納
    
     Private Sub Class_Initialize()
          'クラスItemのコンストラクタ
          m_sProperty1 ="" 'Property1の初期値
     End Sub

     Public Property Get Property1()
          'プロパティProperty1値の取得
          Property1 = m_sProperty1
     End Property
    
     Public Property Let Property1(value)
          'プロパティProperty1値の代入
          If TypeName(value)="String" Then
               m_sProperty1 = value
          Else
               Err.Raise 13 '型が違うときはエラー発生
          End If
     End Property
    
     Public Sub Method1()
          'メソッドMethod1を定義。
          'SubではなくFunctionにすれば値を返すメソッドになる。
          '引数も指定可能
          'ここではProperty1をMsgBoxで表示する例。Meキーワードに注目
          MsgBox Me.Property1
     End Sub
End Class

Class CollectionItems
'クラスCollectionItems。複数のCollectionItemオブジェクトを格納する
     Private m_dicItems '複数のCollectionItemオブジェクトを格納するDictionaryオブジェクト
    
     Private Sub Class_Initialize()
          'CollectionItemsクラスのコンストラクタ
          'Dictionaryオブジェクトを生成
          Set m_dicItems = CreateObject("Scripting.Dictionary")
     End Sub
    
     Public Function Add(CollectionItem)
          'Addメソッド。引数にはCollectionItemオブジェクト
          If IsObject(value) And TypeName(value) = "CollectionItem" Then
               '引数がCollectionItemオブジェクトなら引数をそのまま渡す
               Set oItem = CollectionItem
          Else
               'ほかの引数なら、新しくCollectionItemクラスのインスタンスを作成
               Set oItem = New CollectionItem
          End If
          'DictionaryオブジェクトにCollectionItemオブジェクトを追加
          m_dicItems.Add m_dicItems.Count, oItem
          '生成したor渡されたCollectionItemオブジェクトを戻り値に設定
          Set Add = oItem
     End Function
    
     Public Function Items()
          'Itemsメソッド。CollectionItemオブジェクトの一次元配列を返す
          Items = m_dicItems.Items
     End Function
    
     Public Property Get Count()
          'Countプロパティ(読み取り専用)。格納されているCollectionItemオブジェクトの数を返す
          Count = m_dicItems.Count
     End Property
    
     Public Default Property Get Item(Index)
          'Itemプロパティ(既定)値の取得。Indexに指定されたCollectionItemオブジェクトを返す
          If IsNumeric(Index) Then
               'Indexが数値なら、指定されたCollectionItemオブジェクトを返す
               Set Item = m_dicItems(Index)
          End If
     End Property
    
     Public Property Set Item(Index, value)
          'Itemプロパティ値の設定。Indexに指定したCollectionItemオブジェクトを代入
          If IsObject(value) And TypeName(value) = "CollectionItem" Then
               '引数がCollectionItemオブジェクトなら
               If IsNumeric(Index) Then
                    'Indexが数値なら、引数をDictionaryの指定した位置に代入
                    Set m_dicItems(Index) = value
               End If
          Else
               Err.Raise 13 'オブジェクトが違うときはエラー発生
          End If
     End Property
End Class


'使用方法
Set oItems = New CollectionItems 'CollectionItemsオブジェクトを作成

'コレクションの追加方法その1
oItems.Add(0) '新しいCollectionItemを追加(引数は何でも良い)
Set oItems(0) = New CollectionItem '新しいCollectionItemを生成してItemプロパティに代入
'(↑これはSet oItem(0).Item = New CollectionItemと等価)
oItems(0).Property1 = "hogehoge" 'CollectionItemのProperty1に代入

'コレクションの追加方法その2
Set oItem = oItems.Add(New CollectionItem) '新しいCollectionItemを生成して追加
oItem.Property1 = "mogemoge" 'CollectionItemのProperty1に代入
Call oItem.Method1() 'CollectionItemのMethod1を実行

'コレクションの値の列挙
For Each oItem In oItems.Items() 'CollectionItemsのItemsメソッドを呼び出して配列を取得
     s = s & oItem.Property1 & vbCrLf 'CollectionItemのProperty1プロパティを取得
Next
MsgBox s & oItems.Count '結果をCollectionItemsのCountプロパティとともに返す


本当はRemoveメソッドも作りたかったんですが、コードが複雑になるので省略しました。

管理人むたぐち さん 2006年 01月 13日 19時 56分 12秒

To: ごおお さん

> そのIEでは自動で処理をしてquitするので、そちらにはフォーカスを移し
> たくないのですが、そのようなIEの操作の仕方は可能でしょうか?

IE.Visible = Trueという行でIEのウィンドウを可視化してると思いますが、
これを省略して、非表示のまま実行させてはいかがでしょうか?

Return