外出自粛中でも楽しく過ごす!QAまとめ>>

VBScript初心者です。

VBScriptで配列を扱った処理を作ろうとしています。

具体的には、ファイルAを読み取り、特定の条件に合うものだけをファイルBに書き込みます。
 a.ファイルAを1行ずつ読み込み、配列strに格納
 b.配列strの中から特定の条件に合うものをファイルBにwriteline
ファイルAは毎日行数が変動するファイルです。

困っているのは、配列strを宣言するときに要素数まで指定しないと使えない(ように見える)
ことです。調査不足かもしれませんが、ネット検索上はそう解釈できました。

この場合、上記処置をしようとすると、
1.ファイルAオープン
2.ファイルAの行数を取得
3.ファイルAクローズ
4.配列strを2で取得した行数を要素数として宣言
5.ファイルAオープン
6.上記a,bを実施
となり、ファイルAを2回オープンクローズすることになり、本当にこんなやり方しかないの?
と思ってしまいます。

ReDimという配列の再宣言という概念もあるようですが、再宣言前に格納したデータがすべて
消えてしまう動きに見え、使えそうもありません。
配列を適当に大きな要素数で定義すればできるといえばできますが、上述の通りファイルAは
日々行数が変動するファイルであり、想定を上回る行数になった場合に困るため、適正値の
判断がしにくいです。
それしか手がないならあきらめますが、当方が知らないだけで、ほかに良い方法があるのでは
と期待しております。

不勉強で恐縮ですが、ご教示お願いします。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

redim preserveとすることで、以前の内容が保障されます。


以下のスクリプトを実行してみてください。
redimのサンプルです。
--------------------------------
Option Explicit
Dim stime()
redim preserve stime(0)
stime(0) = "2011/11/18 09:48:25"
redim preserve stime(1)
stime(1) = "2011/11/19 09:48:25"
redim preserve stime(2)
stime(2) = "2011/11/20 09:48:25"
dim st
for each st in stime
WScript.Echo st
next
--------------------------------------
    • good
    • 0
この回答へのお礼

できました。ありがとうございました!

お礼日時:2015/10/18 09:24

というか、


ファイルAを全て読み込まないと、ファイルBに書き出す行が判断できないのですか?
通常ですとファイルから一行ずつ読み取って、その行が書き出す行であれば書き出し、という処理になると思います。
書き出す行の判断に複数行が必要だとしても、変数をフラグに使用するなどすれば実現できると思います。

Set objFS = CreateObject("Scripting.FileSystemObject")
Set objInput = objFS.OpenTextFile("input.txt", 1, False)
Set objOutput = objFS.CreateTextFile("output.txt")

Do While ObjInput.AtEndOfStream <> True
rem 実際は条件に合う行のみ書き込み実施
objOutput.WriteLine(ObjInput.ReadLine)
Loop

objInput.close
objOutput.close
    • good
    • 0

なるほど, preserve なんてものがある, と.

    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q【VBScript】変数のスコープ

変数のスコープについて詳しく教えて下さい。

どこで宣言すれば、どこまで有効か知りたい。

条件分岐やループ、ファンクション等でのスコープが分かりません。

特に、ファンクションの中のファンクションとかです。

参考サイトやヒントだけでも良いので教えて下さい。

Aベストアンサー

少し厳しいかもしれませんが、ご自分でサンプルコードを書いて実行してみましたか?
そういう経験の積み重ねが土台を作る一つの要因になるのだと私は思っています。
もしも検証できない状況にあるのでしたら、ごめんなさい。

かく言う私自身、VBScriptには明るくないので、正しいかどうかわかりませんが、
結論から言うと以下の通りかと思っています。

■結論
・グローバル領域(=いかなるプロシージャにも所属しない領域)で宣言された変数は、どこからでも参照可
・プロシージャ内(←ネストレベルは関係ない)で宣言された変数は当該プロシージャ内のみで有効
・プロシージャのネスト時に参照可能な変数は、グローバル変数と自プロシージャ内で宣言された変数のみ(=自分を呼び出した親プロシージャ内の変数を参照することはできない)
・プロシージャの引数がグローバル変数と同名の場合、引数が優先される
・条件分岐やループの内側か外側かは関係ない(内側で宣言した変数を外側で参照できる)
#プロシージャ≒「ファンクション」です。

■参考URL
http://www.google.com/search?q=vbscript+%E5%A4%89%E6%95%B0+%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97
http://www.keynus.co.jp/~uhara/html/vbscript/16.htm

これで答えになっているでしょうか??

少し厳しいかもしれませんが、ご自分でサンプルコードを書いて実行してみましたか?
そういう経験の積み重ねが土台を作る一つの要因になるのだと私は思っています。
もしも検証できない状況にあるのでしたら、ごめんなさい。

かく言う私自身、VBScriptには明るくないので、正しいかどうかわかりませんが、
結論から言うと以下の通りかと思っています。

■結論
・グローバル領域(=いかなるプロシージャにも所属しない領域)で宣言された変数は、どこからでも参照可
・プロシージャ内(←ネストレベルは関係ない)...続きを読む

QVBScriptでCSVファイルを読み出したい

現在VBScriptでCSVファイルを1行ずつ読み取って、2次元配列に格納するプログラムを作成しています。
CSVファイルの中身は、サンプルで
shop,price,sales
001,500,700
003,1200,90
024,,18 という並びになっています。
実データは300件くらいです。
1行目のヘッダーを読み飛ばし、2行目のデータから1行ずつ読取、","でsplitを用いてまず1次配列に格納しています。
1次元配列のarrLine(0)=001、(1)=500、(2)=700と入ったデータを
2次元配列arrshopに順次保存?したいのです。
----------------------------------------------
dim strLine '1行ずつ読込んだデータを持つ
dim ntLineNum '行数のカウント
dim arrLine '","で区切った要素を持つ一次元配列
dim arrshop '一次元配列になった要素を2次元配列として格納

Do until .AtEndOfStream
  strLine = .ReadLine
  if 0<>strComp("",Trim(strLine)) then
ntLineNum = intLineNum + 1
  end if
  arrLine = split(strLine , ",")
  arrshop = Array(arrLines,i)
i = i + 1
loop
-----------------------------------------
msgbox arrshop(2)(0) と指定すると「003」出るようにしたいです。
Array関数が上手くないような気もします・・・。
どなたかご教授お願いします(>_<。)

現在VBScriptでCSVファイルを1行ずつ読み取って、2次元配列に格納するプログラムを作成しています。
CSVファイルの中身は、サンプルで
shop,price,sales
001,500,700
003,1200,90
024,,18 という並びになっています。
実データは300件くらいです。
1行目のヘッダーを読み飛ばし、2行目のデータから1行ずつ読取、","でsplitを用いてまず1次配列に格納しています。
1次元配列のarrLine(0)=001、(1)=500、(2)=700と入ったデータを
2次元配列arrshopに順次保存?したいのです。
--------------------------...続きを読む

Aベストアンサー

Arrayのところがおかしいですね。

動くか検証してないですが…
arrshop = Array(arrLines,i)
の代わりに
Redim Preserve arrshop(i+1)
arrshop(i)=arrLines
でやってみてください。
それと最初にiは0か1にでも初期化してから使う事をお勧めします。

QVBSで"をエスケープする文字は?

VBSで"をエスケープする文字はなんでしょうか?

Aベストアンサー

エスケープといった考えが VBSではなかったように思います

"をあらわすには "で括る必要が生じます
たとえば "abc" といった内容なら """abc""" といったリテラルになります
一番外側の "のペアが 文字列としての"になります

"ab"cが欲しいなら """ab""c"
a"bc"が欲しいなら "a""bc"""
a"b"cがほしいなら "a""b""c"
といった具合になります

QVBA オブジェクトが空かどうか判定する

皆様のお知恵を拝借させてください。

エクセルVBAでオブジェクトを入れる変数を定義し、その変数にオブジェクト
が入っているかどうか検査したいのですがどうしたらいいでしょうか。

例えば---
Dim a As Workbook
If a <> nothing then ←この部分が分からない。このままだとエラー。
処理
End if
---------
環境
エクセル2003
WinXPsp1

Aベストアンサー

もし、aが空だったら
If a Is Nothing Then 

もし、aが空じゃなかったら
If Not a Is Nothing Then

QVBS実行時エラー オブジェクトがありません 回避方法について

タイトルの件ですが、現在CSVよりIDとPWを読み込み、Webページに自動ログインできるVBSを作成しております。
ネットの情報を頼りに下記ソースを作成し、自動ログインできるところまでは達成しました。
しかしながら、一回目の実行時はいいのですが、二回目以降時間を置かずにVBSを起動すると
エラーが発生します。(IEは起動し、ログイン自体は出来ます)
本エラーの回避方法をご教授願えませんでしょうか。

エラーの発生場所は objIE.Document.getElementsByName("username")(0).Value = SiteID
あたりだとは思うのですが、何が原因かがわからなく。。

○エラーメッセージ
エラー:オブジェクトがありません。:'objIE.Document.getElementByName(...)(...)'
コード:800A01A8
ソース:Microsoft VBScript 実行時エラー

○コード
'Option Explicit

Dim tmp 'CSV格納
Dim tmp2 'CSV分割
Dim SiteArray(10) 'ID,PW,URL格納
Dim SiteURL 'URL格納
Dim SiteID 'ID格納
Dim SitePW 'PW格納

Dim i
dim objFSO
dim stmCsvFile

'URL,ID,PWをCSVより読込
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set stmCsvFile = objFSO.OpenTextFile("C:\Users\***\Desktop\login.csv")

Do Until stmCsvFile.AtEndOfLine = True
tmp = stmCsvFile.readline
tmp2 = Split(tmp, ",")
SiteArray(i) = tmp2(1)
i = i + 1
Loop

stmcsvfile.Close


'URL,ID,PWを格納
SiteID = SiteArray(1)
SitePW = SiteArray(2)
SiteURL = SiteArray(0)

'---------- ひらく

Set objIE = CreateObject("InternetExplorer.application")
objIE.Visible = True
objIE.Navigate SiteURL
Do Until objIE.busy = False And objIE.readyState = 4 : Loop '待ち合わせ

'---------- ID/PASSの入力

objIE.Document.getElementsByName("username")(0).Value = SiteID
objIE.Document.getElementsByName("password")(0).Value = SitePW

'---------- SUBMIT

objIE.Document.getElementsByName("login_form")(0).Submit
Do Until objIE.busy = False And objIE.readyState = 4 : Loop '待ち合わせ

'----------

宜しくお願い致します。

タイトルの件ですが、現在CSVよりIDとPWを読み込み、Webページに自動ログインできるVBSを作成しております。
ネットの情報を頼りに下記ソースを作成し、自動ログインできるところまでは達成しました。
しかしながら、一回目の実行時はいいのですが、二回目以降時間を置かずにVBSを起動すると
エラーが発生します。(IEは起動し、ログイン自体は出来ます)
本エラーの回避方法をご教授願えませんでしょうか。

エラーの発生場所は objIE.Document.getElementsByName("username")(0).Value = SiteID
あたりだ...続きを読む

Aベストアンサー

こんにちは。

>コメント頂いた箇所を下記の通り処理を変更しましたが現象はほぼ変わりませんでした。

#1で私の書いた、IsObjectは一般論ですが、個別の問題になるとかなり話は込み入ってしまうから、やめておいたことですが、なんといっても、VBSで、どのように開発しているかは分かりませんが、そのオブジェクトのプロパティとか、確認をして開発したのでしょうか。

>Set upw =objIE.Document.getElementsByName("password")
の時点で、upw を確認できない状態ですと、
upw(0) という「添字(index)」があるかどうかさえ確認できませんよね。
その辺りはどうなんでしょうか?それで、Length プロパティを調べるように書いたわけです。

ふつう、例えば、ここの「教えて!goo」なんかでも、IDとパスワードは、きちんと、[ID(uname, pass)]を持っています。そしてIDには、添字は存在しません。

VBAがあれば、VBEditorのローカルウィンドウで、そのプロパティを確認していただくしかないと思います。もしかしたら、最初からとれていないのかもしれません。

こんにちは。

>コメント頂いた箇所を下記の通り処理を変更しましたが現象はほぼ変わりませんでした。

#1で私の書いた、IsObjectは一般論ですが、個別の問題になるとかなり話は込み入ってしまうから、やめておいたことですが、なんといっても、VBSで、どのように開発しているかは分かりませんが、そのオブジェクトのプロパティとか、確認をして開発したのでしょうか。

>Set upw =objIE.Document.getElementsByName("password")
の時点で、upw を確認できない状態ですと、
upw(0) という「添字(index)」があるか...続きを読む

QVBScripの2次元動的配列

下記VBScripサンプルで2次元動的配列をつかっているのですが
redim preserveでエラになります。
(インデックスが有効範囲にありません)
原因をご伝授ください。
環境 IIS 5.0
Windows XP

index.asp

<%@ LANGUAGE="VBScript" %>
<% 'option explicit %>
<!-- #include file="test.asp" -->
<%
Dim Order()
Dim dat()
call test(Order,dat)
response.write("dat=" & dat(1,2))

%>

test.asp

<%'Option Explicit%>
<%
function test(Order_info,dat)

Dim i
redim dat(0,7)
for i=0 to 1 <- iが0の時はOK,iが1になるとエラー
redim preserve dat(i,7)
dat(i,1)="1"
dat(i,2)="2"
dat(i,3)="3"
dat(i,4)="4"
dat(i,5)="5"
dat(i,6)="6"
next

End function

下記VBScripサンプルで2次元動的配列をつかっているのですが
redim preserveでエラになります。
(インデックスが有効範囲にありません)
原因をご伝授ください。
環境 IIS 5.0
Windows XP

index.asp

<%@ LANGUAGE="VBScript" %>
<% 'option explicit %>
<!-- #include file="test.asp" -->
<%
Dim Order()
Dim dat()
call test(Order,dat)
response.write("dat=" & dat(1,2))

%>

test.asp

<%'Option Explicit%>
<%
function test(Order_info,dat)

Dim i
redim dat(0,7)
for...続きを読む

Aベストアンサー

ReDimで変更できるのは最終次元の添え字です

dim dat(0,7)
と宣言した場合 変更できるのは 2次元目の7側の次元です
つまり ReDim dat( 0, 8 )や ReDim dat( 0, 3 ) は許されますが
ReDim dat(1,7) など 1次元目の変更は出来ません

直感的ではないかもしれませんが添え字が固定のものを1次元目にして対処してみてはいかがでしょう

redim dat(7,0)
for i=0 to 1
  redim preserve dat(7,i)
  dat(1,i)="1"
  dat(2,i)="2"
  dat(3,i)="3"
  dat(4,i)="4"
  dat(5,i)="5"
  dat(6,i)="6"
next
といった具合で ...

QVBSで特定の文字列が含まれる場合の処理方法

こんにちは。
自分史上初めて投稿します。

テキストファイルを簡単に操作出来るということを聞いて、さいきんVBSを勉強し始めました。
そこで、特定のファイルの中身を読み込んで配列関数を使い配列に格納した後、特定の文字列が含まれる場合には別の文字列へと変換したいと思っているのですが、正規表現が上手くいきません(汗)

どなたか助けていただけませんでしょうか?
それともそもそも正規表現が使えないなんてことはないですよね・・・?


よろしくお願いいたします。
ちなみに書いたコードは↓

Set WSHFso = CreateObject("Scripting.FileSystemObject")
Set WshShell = WScript.CreateObject("WScript.Shell")
Dim strSearchWord

Set tmpFile = WSHFso.OpenTextFile("C:\Documents and Settings\●●●\○○.txt")

Do Until tmpFile.AtEndOfStream
tmpLine = tmpFile.ReadLine
strSearchWord = strSearchWord & tmpLine & vbcrlf
Loop


Dim SearchWord
SearchWord = split(strSearchWord,"")


Select Case SearchWord(9)


'ここで『東京』というワードが含まれる場合に別処理を走らせたいのです・・・。
Case "*" & "東京" & "*"

msgbox SearchWord(10)

Case Else

msgbox SearchWord(101)

End Select

こんにちは。
自分史上初めて投稿します。

テキストファイルを簡単に操作出来るということを聞いて、さいきんVBSを勉強し始めました。
そこで、特定のファイルの中身を読み込んで配列関数を使い配列に格納した後、特定の文字列が含まれる場合には別の文字列へと変換したいと思っているのですが、正規表現が上手くいきません(汗)

どなたか助けていただけませんでしょうか?
それともそもそも正規表現が使えないなんてことはないですよね・・・?


よろしくお願いいたします。
ちなみに書いたコード...続きを読む

Aベストアンサー

配列SearchWordの要素の文字列を置換したいのでしたら下のような感じでしょうか。Select Caseステートメントでは正規表現は使えないと思います。

Windows XP SP2 + WSH VBScript 5.6で試しました。

-----
Dim strSearchWord
Dim SearchWord
strSearchWord = "東京 東京駅 西東京 西東京は東京の西 品川"
SearchWord = Split(strSearchWord," ")

Set regEx = New RegExp
regEx.Pattern = "東京"
regEx.Global = True

For ix=0 to UBound(SearchWord)
SearchWord(ix) = regEx.Replace(SearchWord(ix), "神田")
Next

WScript.Echo Join(SearchWord, " ")
-----

なお、特定の単純な文字列が含まれているか調べるには、正規表現を使わなくてもInStr関数でよさそうです。「別処理」でやりたいことの内容にもよりますが。

-----
if InStr(SearchWord(ix), "東京")<>0 then
WScript.Echo SearchWord(ix) & " は東京を含みます。"
else
WScript.Echo SearchWord(ix) & " は東京を含みません。"
end if
-----

配列SearchWordの要素の文字列を置換したいのでしたら下のような感じでしょうか。Select Caseステートメントでは正規表現は使えないと思います。

Windows XP SP2 + WSH VBScript 5.6で試しました。

-----
Dim strSearchWord
Dim SearchWord
strSearchWord = "東京 東京駅 西東京 西東京は東京の西 品川"
SearchWord = Split(strSearchWord," ")

Set regEx = New RegExp
regEx.Pattern = "東京"
regEx.Global = True

For ix=0 to UBound(SearchWord)
SearchWord(ix) = regEx.Replace(SearchW...続きを読む

QVBSで変数の宣言はできないのですか?

VBSで、

Dim a As String
a = InputBox("MsgBoxに表示する値を入れてください。", , "test")
MsgBox a

と文章を作って、test.vbsで保存しました。
するとエラーになります。

Dim a As Stringの部分を消すと、問題なく作動します。

もしくは、

Dim a
a = InputBox("MsgBoxに表示する値を入れてください。", , "test")
MsgBox a

でも正常に動きます。
VBSで変数の宣言はできないのでしょうか?

Aベストアンサー

こっちの方がより面白いか。
自動型変換の便利さと危うさですね。

dim a
msgbox typename(a)
a=1
msgbox "a= " & a & " typename= " & typename(a)

a=a*100000
msgbox "a= " & a & " typename= " & typename(a)

a=a*0.1
msgbox "a= " & a & " typename= " & typename(a)

a= a & "b"
msgbox "a= " & a & " typename= " & typename(a)

a=a*1

Q[VBS] 動的配列について教えてください!

VBS初心者です。
以下のように、リストを読み込んで動的配列に持たせたいです。

-----------------------------------------------------------------

GET_FILE = "sample.txt"
SET objFs = CreateObject("Scripting.FileSystemObject")

' 動的配列セット
Call Array_Set("AryVal",GET_FILE)

' 表示
For i = 0 To Ubound(AryVal)
msgbox AryVal(i)
Next

' 終了
WScript.Quit 0

Function Array_Set(AryName,ReadFile)

Set strVal = objFs.OpenTextFile(ReadFile)

' 1行づつ処理
Do While strVal.AtEndOfStream <> True

i = i + 1

ReDim Preserve AryName( i - 1 )

AryName( i - 1 ) = strVal.ReadLine

Loop

End Function
-----------------------------------------------------------------

見て頂くと分かるとおり、動的配列として持たせたい変数名を
Functionの引数として渡しています。(当然のごとくエラー、、、)
Functionの引数として渡した値に動的配列が格納される方法があれば教えてください。
よろしくお願いします。

VBS初心者です。
以下のように、リストを読み込んで動的配列に持たせたいです。

-----------------------------------------------------------------

GET_FILE = "sample.txt"
SET objFs = CreateObject("Scripting.FileSystemObject")

' 動的配列セット
Call Array_Set("AryVal",GET_FILE)

' 表示
For i = 0 To Ubound(AryVal)
msgbox AryVal(i)
Next

' 終了
WScript.Quit 0

Function Array_Set(AryName,ReadFile)

Set strVal = objFs.OpenTextFile(ReadFile)

' 1行づつ処理
Do While strVal.AtEndOfSt...続きを読む

Aベストアンサー

変数をパブリック宣言しておいて
名前ではなく変数そのものを渡してあげれば。


Public AryVal()

GET_FILE = wscript.scriptfullname '"sample.txt"

SET objFs = CreateObject("Scripting.FileSystemObject")

' 動的配列セット
Call Array_Set(AryVal,GET_FILE)

・・・以下は冒頭の質問と同じなので省略しました。

QVBScriptで配列のソートをするには?

VBScriptで作成した配列の順番をソートする場合、どのようなコーティングを行えば、実現できるでしょうか?
ソートそのものを実装する関数がありますか?

Aベストアンサー

簡単なものなら
シンプルソート、バブルソート
再起呼び出しなどを使えるレベルならば
マージソート、クイックソート

これらのアルゴリズムの名前で検索をかければ
プログラム例が載っているサイトがみつかりますよ。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング