--.--.--

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

2009.12.24

第353夜

vbs(wsh)のお勉強1日目・・・。

もしかしたらVBじゃなくてVBSなのかも。
困った。両方やってる時間ないし(/ω\)

素養も経験もなく、今回springね。次vbねって毎回違うの簡便してほしいな・・・。
広く浅くじゃ何の役にも立たないし、毎回毎回こう胃がきりきりと・・・。
辞めようと思った5年前を思い出すな~。今回なんかあれに似てる気がする。

まぁ、できるだけの準備はしよう・・・欝だ。
この記事へのトラックバックURL
http://hexagram.blog41.fc2.com/tb.php/375-22c765b8
この記事へのトラックバック
この記事へのコメント
Q.型の宣言を強制したい場合

A.Option Explicitを先頭に記述する。
Posted by hexagram at 2009.12.24 00:14 | 編集
Q.VBSの型の種類は?

A.バリアント型のみらしい。
内部処理の型としては文字列型とか日付型とかあるらしいけど。
Posted by hexagram at 2009.12.24 11:35 | 編集
Q.改行文字を入力したい場合

A.vbCrLfを記述する。
Posted by hexagram at 2009.12.24 11:39 | 編集
Q.ProgIDを調べたい場合

A.随時更新予定。

1.OLE/COM オブジェクトビューアーというのがあるらしいけど、VC++のツールのようで持っていない。

どこかでProgIDが表示されていたような気もするんだけど・・・。
systemscripterで調べられなかったかな~。会社のにはインストールしてみたから、28日に行ったら調べてみようかな。

英語だったけどダウンロードセンターで"oleview"で検索したらあった。
・・・が、起動しようとしたら警告がでた。
どうも"IVIEWERS.DLL"がないらしい。

同梱しておいてYO
探している内にカスペルスキーが警告出すサイトに出くわしたじゃないかw
というかURL踏んで初めて出たから焦った。

検索して別のサイトからダウンロードして、system32においても同じ。
あれ?
systemにおいてもだめ。警告のyesボタンを押しちゃおうかと思ったけど、思い留まってoleviewerのディレクトリに置いたら警告消えた(*´Д`*)
ただdllのバージョンが正しいかは不明(/ω\)
警告とかエラー出てないから取り合えずはいいか。

これでProgIDを見つける方法が1つ増えた?

2.レジストリエディタでHKEY_CLASSES_ROOT配下のフォルダ名がProgIDのようだ。

ちなみにサブフォルダにCLSIDがあるが、スクリプトではProgIDを指定するが、内部でCLSIDに変換されてCOMオブジェクトを呼び出すらしい。
Posted by hexagram at 2009.12.24 15:36 | 編集
Q.パスとファイル名を連結させたい場合

A.BuildPathを使用する。

strFileName = objFSO.BuildPath("C:kyonko",objFSO.GetTempName())

単純に文字列結合の"&"を使用する方法もあるが、パスの最後に""がある場合とない場合が混在する場合に適切に処理してくれるらしいので、BuildPathを使用した方がよいと思われる。
Posted by hexagram at 2009.12.24 18:22 | 編集
Q.ファイルの存在チェックをしたい場合

A.FileExistsを使用する。

If Not objFSO.FileExists(strFileName) Then
MsgBox strFileName & "というファイルは存在しません。"
WScript.Quit
End If
Posted by hexagram at 2009.12.24 18:23 | 編集
Q.ランダムなファイル名を取得したい場合

A.調査中。

GetTempNameを使用すれば拡張子がtmpになるランダムなファイル名が取得できるが・・・。
これを使用した後に拡張子を変えたりするのだろうか?
Posted by hexagram at 2009.12.24 18:33 | 編集
Q.ファイルを移動(存在する場合は上書き)する場合

A.未調査。

MoveFileでファイルを移動できるようだが、ファイルが存在するとエラーになるらしい。
CopyFileでは引数で上書き設定が可能のようだが・・・。
ファイルの存在チェックを先にしてあったら、削除した上でMoveFileを使用する方法しかないのだろうか?
Posted by hexagram at 2009.12.24 19:21 | 編集
Q.エラー処理をしたい場合

A.今回は大まかに。

エラーになる可能性があるコードをOn Error Resume NextとOn Error Goto 0ステートメントで囲み、その中でErrオブジェクトを参照し、Err.Numberが0でない場合にエラー処理を行うらしい。

例)
If Err.Number <> 0 Then
MsgBox Err.Number & ": " & Err.Description, vbCritical
End If
Posted by hexagram at 2009.12.24 20:19 | 編集
Q.エラーナンバーの一覧は?

A.VBScriptのエラーナンバーは下記にのっているようだが、これ以外にもあるのかも。
例えば呼出先のCOMとかWMIとか(自分でもよく分かってないけど)。

ttp://www.upken.jp/wiki/index.php?VBScript%2FErr%E7%95%AA%E5%8F%B7%E8%A1%A8
Posted by hexagram at 2009.12.24 20:32 | 編集
Q.サンプルがほしい場合

A.随時更新予定。

ttp://www.upken.jp/wiki/?VBScript
Posted by hexagram at 2009.12.24 20:32 | 編集
Q.ファイルやフォルダの属性を取得したい場合

A.未調査。

Attributesを使用する。
上記プロパティで取得した値を下記のような関数で加工すると見やすいかも?
下記はショートカットや圧縮ファイルが認識しないし、標準ファイルなど未確認。

Function GetAttributes(lngAttribute)
Const Normal = 0 '標準ファイル
Const ReadOnly = 1 '読み取り専用ファイル
Const Hidden = 2 '隠しファイル
Const System = 4 'システム・ファイル
Const Volume = 8 'ディスク・ドライブ・ボリューム・ラベル。値の取得のみ可能
Const Directory = 16 'フォルダまたはディレクトリ。値の取得のみ可能
Const Archive = 32 'アーカイブ
Const Alias = 64 'リンクまたはショートカット。値の取得のみ可能
Const Compressed = 128 '圧縮ファイル。値の取得のみ可能

'↓意味がまだ分からない。
If (lngAttribute And Normal) = Normal Then GetAttributes = GetAttributes & "標準 "
If (lngAttribute And ReadOnly) = ReadOnly Then GetAttributes = GetAttributes & "読み取り専用 "
If (lngAttribute And Hidden) = Hidden Then GetAttributes = GetAttributes & "隠しファイル "
'↓未確認。
If (lngAttribute And System) = System Then GetAttributes = GetAttributes & "システム "
'↓未確認。
If (lngAttribute And Volume) = Volume Then GetAttributes = GetAttributes & "ディスク・ドライブ・ボリューム・ラベル "
'↓未確認。
If (lngAttribute And Directory) = Directory Then GetAttributes = GetAttributes & "フォルダ "
'↓意味がまだ分からない。
If (lngAttribute And Archive) = Archive Then GetAttributes = GetAttributes & "アーカイブ "
'↓うまくいかない。
If (lngAttribute And Alias) = Alias Then GetAttributes = GetAttributes & "リンクまたはショートカット "
'↓うまくいかない。
If (lngAttribute And Compressed) = Compressed Then GetAttributes = GetAttributes & "圧縮 "
End Function
Posted by hexagram at 2009.12.24 21:38 | 編集
Q.MsgBoxに文字列が全て表示されない。

A.仕様のようです。
WScript.Echoで確認すると表示されるので、文字列の設定に不備はない。
MsgBoxの引数に設定できるのが1,024文字らしい。
Posted by hexagram at 2009.12.25 02:28 | 編集
Q.ファイルをUTF-8で書き込みたい場合

A.ADODB.Streamを使用するらしい。

例)
Dim objIn, objOut

Dim fileName : fileName = "test.txt"
Dim text : text = "あいうえお"

Call saveFile(fileName, text)

Sub saveFile(fileName, text)
On Error Resume Next

' ADODB.Streamのモード
Dim adTypeBinary : adTypeBinary = 1
Dim adTypeText : adTypeText = 2
Dim adSaveCreateOverWrite : adSaveCreateOverWrite = 2

' ADODB.Streamを作成
Dim pre : Set pre = CreateObject("ADODB.Stream")
' 最初はテキストモードでUTF-8で書き込む
pre.Type = adTypeText
pre.Charset = "UTF-8"
pre.Open()
pre.WriteText(text)
' バイナリモードにするためにPositionを一度0に戻す
' Readするためにはバイナリタイプでないといけない
pre.Position = 0
pre.Type = adTypeBinary
' Positionを3にしてから読み込むことで最初の3バイトをスキップする
' つまりBOMをスキップします
pre.Position = 3
Dim bin : bin = pre.Read()
pre.Close()

' 読み込んだバイナリデータをバイナリデータとしてファイルに出力する
' ここは一般的な書き方なので説明を省略
Dim stm : Set stm = CreateObject("ADODB.Stream")
stm.Type = adTypeBinary
stm.Open()
stm.Write(bin)
stm.SaveToFile fileName, adSaveCreateOverWrite ' force overwrite
stm.Close()
End Sub
Posted by hexagram at 2009.12.25 11:36 | 編集
Q.バイナリを書き込みたい場合

A.ADODB.Streamを使用するらしい。

例)
Option Explicit

dim objOut
dim objIn

set objOut = CreateObject("ADODB.Stream")
set objIn = CreateObject("ADODB.Stream")

With objOut
'テキストモードを表している?
.type = 2
.charset = "iso-8859-1"
.open
End With

dim i

'&hff(16進数?)は255(10進数?)。
For i = 0 to &hff
objOut.writeText(ChrW(i)) 'uses ChrW
next

'第二引数は上書きモードを表している。
objOut.saveToFile "test123.bin", 2
objOut.close

With objIn
'バイナリモードを表している。
.type = 1
.open
End With

objIn.LoadFromFile("test123.bin")

dim line
dim msg
dim ch

line = objIn.Read
msg = ""

For i = 1 To LenB(line)
ch = AscB(MidB(line, i ,1))
msg = msg & " " & Hex(ch)
Next

objIn.Close

Wscript.Echo msg
Posted by hexagram at 2009.12.25 12:01 | 編集
Q.バイナリファイルを指定文字毎に改行したい場合

A.バイナリファイルを改行することに意味があるかは分からないけど・・・。

例)
'バイナリファイルを指定文字毎に改行する。
Dim objIn, objOut

'改行コードを作成
Dim objTmp

Set objTmp = CreateObject("ADODB.Stream")
objTmp.Type = 2 'テキストモード
objTmp.Charset = "shift_jis"
objTmp.Open
objTmp.WriteText vbCrLf

objTmp.Position = 0
objTmp.Type = 1

Dim objCrLf

objCrLf = objTmp.Read(2)

Set objTmp = Nothing

'本体処理
If WScript.Arguments.Count = 3 Then
Set objIn = CreateObject("ADODB.Stream")
Set objOut = CreateObject("ADODB.Stream")

objIn.Type = 1
objIn.Open
objOut.Type = 1
objOut.Open

objIn.LoadFromFile(WScript.Arguments(0))

Dim iLen

iLen = CInt(WScript.Arguments(2))

Do Until objIn.EOS
line = objIn.Read(iLen)
objOut.Write line
objOut.Write objCrLf
Loop

objOut.SaveToFile WScript.Arguments(1), 2
Else
WScript.Echo "引数エラー"
End If
Posted by hexagram at 2009.12.25 12:28 | 編集
初書き込みで申し訳ないんですが、都合のいい男性探しています。不況の中でも会社が高成長してて、忙しい毎日です。お陰でプライベートが充実していなくって、溜まる一方です。財産的にも多少余裕が今のところあるのでお礼もできます。何より、この書き込みが読まれているのかちょっと怪しいですけど…。アドレス置いとくので、消されないうちにメールくれたら嬉しいです。inspiration.you@docomo.ne.jp
Posted by るな at 2009.12.25 13:28 | 編集
Q.VbsEditで実行したい場合

A.Startボタンをクリックで実行される。

カレントはvbsのあるディレクトリになるみたい。
Posted by hexagram at 2009.12.25 13:36 | 編集
Q.VbsEditで1行ずつ実行したい場合

A.未調査
Posted by hexagram at 2009.12.25 13:37 | 編集
Q.スクリプトファイルのフォルダを取得したい場合

A.WScript.ScriptFullNameを使用する。
Posted by hexagram at 2009.12.25 13:42 | 編集
Q.連想配列は同じキーを登録しようとするとエラーになるが、どう対応するのか?

A.最初に存在するかチェックをする方法がある。
上書きしたいのならば、一度削除してから登録すればよいのではないか?

例)
If Not objDictionary.Exists("yuki") Then
objDictionary.Add "yuki", "Miyuki Takara"
Else
objDictionary.Remove "yuki"
objDictionary.Add "yuki", "yukikaze"
End If
Posted by hexagram at 2009.12.25 16:47 | 編集
Q.コマンドライン出力をリダイレクトさせるには?

A.下記のように行う。

例)
Set shell= WScript.CreateObject("WScript.Shell")

shell.Run "%ComSpec% /c dir > abc.txt"
'追記モードにしたい場合
'shell.Run "%ComSpec% /c dir >> abc.txt"
Posted by hexagram at 2009.12.25 17:20 | 編集
Q.配列の要素数を動的に増やしたい場合

A.ReDimを使用する。

Dim strName()
ReDim strName(要素数 - 1)

多元配列の場合は
ReDim strName(行数 - 1, 要素数 - 1)

注意点としてはReDimした時点で値はクリアされること。
クリアしたくない場合は下記のようにすること。

ReDim Presserve strName(要素数 - 1)

但し多元配列の場合はPresserveを使えるのは最終次元のみなので注意すること。
Posted by hexagram at 2009.12.25 17:41 | 編集
Q.バブルソートをしたい場合

A.最後表示のところが適当だけど(カンマで終わる辺り)・・・こんな感じ?

Option Explicit

Dim a(10)

a(1) = 9
a(2) = 15
a(3) = 2
a(4) = 10
a(5) = 8
a(6) = 7
a(7) = 25
a(8) = 11
a(9) = 3
a(10) = 4

Dim last : last = 9

Do
Dim gyakuten : gyakuten = 0
Dim i

For i = 1 To last
If a(i) > a (i + 1) Then
Dim temp : temp = a(i)
a(i) = a(i + 1)
a(i + 1) = temp
gyakuten = 1
End If
Next

last = last -1
Loop While gyakuten = 1
Dim j

For j = 1 To 10
Dim kekka : kekka = kekka & a(j) & ", "
Next

MsgBox kekka, , "並べ替えた結果"
Posted by hexagram at 2009.12.25 17:56 | 編集
Q.他のvbsで定義した関数を呼び出す方法は?

A.未調査。

Wscript.ShellのRunやexecを使用すれば、vbs自体を起動することはできるらしいけど、vbs自体を起動したいのではなくて、他のvbsの関数を使いたい。

a.vbs, b.vbs, c.vbsで同じ処理があったら、それを抜き出してd.vbsにいれておいて、a.vbs, b.vbs, c.vbsで呼び出すようにしたい。
d.vbsは関数の集合。

d.vbsの引数に関数名とか渡すしかないんだろうか。
d.vbsがクラスだったらどうするんだろう。
Posted by hexagram at 2009.12.25 18:09 | 編集
Q.クリップボードからテキストを読み込む場合

A.ieやofficeの機能を使用するらしい。
ただセキュリティの関係でできないこともあるらしいし、アクセス許可を求める画面がでるのが困る。

例)ieを利用
Option Explicit

Dim Ie

Set Ie = WScript.CreateObject("InternetExplorer.Application")
Ie.Navigate "about:blank"

Do While Ie.Busy
WScript.Sleep 10
Loop

'クリップボードの文字列を取得
Dim sClipBoard

sClipBoard = Ie.Document.parentWindow.clipboardData.getData("text")

Ie.Quit

MsgBox sClipBoard

例)officeを利用
'クリップボードから読み取り(office利用)
Option Explicit

Dim uf
Dim tb

Set uf = CreateObject("Forms.Form.1")
Set tb = uf.Controls.Add("Forms.TextBox.1").Object
tb.MultiLine = True

If tb.CanPaste Then
tb.Paste
WScript.StdOut.Write tb.Text
End If

Set tb = Nothing
Set uf = Nothing
Posted by hexagram at 2009.12.25 19:34 | 編集
Q.クリップボードにテキストを書き込む場合

A.ieやofficeの機能を使用するらしい。
ただセキュリティの関係でできないこともあるらしいし、アクセス許可を求める画面がでるのが困る。

例)ieを利用
'クリップボードに書き込み(ie利用)
Option Explicit

Dim Ie

Set Ie = WScript.CreateObject("InternetExplorer.Application")
Ie.Navigate "about:blank"

Do While Ie.Busy
WScript.Sleep 10
Loop

Ie.Document.parentWindow.clipboardData.setData "text", "あいうえお"
'Ie.Document.parentWindow.clipboardData.clearData "text"
Ie.Quit

例)officeを利用
こちらはコマンドプロンプトから実行するらしい。
入力したらCtrl+Zを押した後にリターンを押すと入力が終了するみたい。

'クリップボードに書き込み(office利用)
Option Explicit

Dim Text
Dim uf
Dim tb

Text = WScript.StdIn.ReadAll
Set uf = CreateObject("Forms.Form.1")
Set tb = uf.Controls.Add("Forms.TextBox.1").Object
tb.MultiLine = True
tb.Text = Text
tb.SelStart = 0
tb.SelLength = tb.TextLength
tb.Copy

Set tb = Nothing
Set uf = Nothing
Posted by hexagram at 2009.12.25 19:41 | 編集
Q.なんかいいエディタはないか?

A.キーワードに色か付く機能や、コード補完機能があるエディタがよさそう。

systemscripterが中々良さそうですが、シェアウェアなのが残念。
高くはないのでいいものであれば払ってもいいのですが、英語圏なので私にはハードルが高い。
ベクターとかで支払えればよかったんだけど、ちょっと怖くて購入できない。

WSHAssistantというエディタにアシスト機能を付けるのもあるようです。
使えるエディタと使えないエディタがあるようです。

これとterapad辺りにしようかなと思っていたのですが、vbseditといういい感じのものが見つかったので試していません。

vbseditも英語圏でシェアウェアですが、そのままでも使えるようです。
ちょっとポップアップとか、スクリプト実行に数秒待たされるとかありますが、十分許容範囲内です。

キーワードに色もつくし、コード補完もあります。
Microsoft Script debuggerというのをインストールして連携すれば1行ずつデバッグとかもできるらしいです。

ただ英語でよく分からないのと、インストールしてもうまくできないっていうことをwebでよくみるので、インストールはしていません。

実行自体はできるから、いまのところこれで十分。
いやできればもっと売れしいんですけどね。
Posted by hexagram at 2009.12.25 20:56 | 編集
Q.Microsoft Script Debuggerのインストールと使い方は?

A.未調査。
Posted by hexagram at 2009.12.25 22:22 | 編集
Q.MSDNライブラリをインストールしたい場合は?

A.未調査。

MSDNライブラリはフルバージョンと軽量版(Express edition)の2種類ある。
フルバージョンはisoイメージなので、仮想ドライブで読み込むか、DVDに焼いてからインストールする。
軽量版はexeファイルなので実行すればよい。

いまVisual Basic 2008 Express editionをインストールしているのだけど、フルバージョンをインストールしていいかは調査中。

またどこかで、MSDNライブラリとWindows SDK(?)やらなんやらは関連していて、MSDNをアンインストールすると、他のが動かなくなる既知の不具合があるらしい。

.NET frameworkをどれも参照しているとかなんとかだったかな、あんまり覚えてない。

要するにMSDNライブラリを入れたら、もしアンインストールする必要がある場合は事前によく調べる必要があるってこと。
Posted by hexagram at 2009.12.26 00:49 | 編集
管理者にだけ表示を許可する
 
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。