2022年5月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
無料ブログはココログ

« 2008年2月 | トップページ | 2008年4月 »

2008年3月30日 (日)

空白は、ファイル名の途中には使えますが、先頭や末尾にも使える?

ファイル名の先頭には使えますが、末尾には使えません。

その裏返しで、ファイル名の末尾に空白を付けても無視されます。

これは、OSレベルの仕様です。

つまり、"aaa.txt" というファイルは、"aaa.txt   " を指定しても開けます。

Set fso=CreateObject("Scripting.FileSystemObject")
Set File=fso.OpenTextFile("aaa.txt   ")
MsgBox File.ReadAll()

OSレベルの仕様なので、アプリの起動でも同じです。

例えば、"fc.exe" は、"fc.exe  " でも起動できます。

2008年3月29日 (土)

オフラインで使用できない Web ページ (その2)

先のHTMLファイルから、
<BASE HREF="元のページのURL">
を削除しても、[オフライン作業]のままでは、更に、以下のダイアログが出ます。

--------------------------------------------
オフラインで使用できない Web ページ
--------------------------------------------
要求された Web ページは、オフラインで使用できません。
このページを表示するには [接続] をクリックしてください。
[ 接続(C) ] [ オフライン継続(S) ]
--------------------------------------------

この場合は、HTMLファイルから、
<IFRAME ~~~ src="http://~~~">~~~</IFRAME>
を削除すれば、[オフライン作業]でも、このダイアログが出なくなるようです。

2008年3月27日 (木)

オフラインで使用できない Web ページ

例えば、Googleで検索して、キャッシュをHTMLのみで保存して、[オフライン作業]で表示すると、

--------------------------------------------------
オフラインで使用できない Web ページ
このページは、インターネットに接続していないと表示できません。
--------------------------------------------------

というページが表示されます。

こういうときは、[オフライン作業]を外して、表示するか、
あるいは、HTMLファイルから、
<BASE HREF="元のページのURL">
を削除すれば、[オフライン作業]でも表示できるようです。

参考) IEの「ファイル」-「オフライン作業」メニュー項目を出す。
http://scripting.cocolog-nifty.com/blog/2007/07/ie_b52d.html

2008年3月26日 (水)

スクリプトからExcelのマクロシートを動的に作成して実行する。

VBAの場合は、VBA プロジェクト オブジェクト モデルへのアクセスが制限されていますが、マクロシートなら自由に書けます。

Set Application=CreateObject("Excel.Application")
Application.Visible=True
Set Book=Application.Workbooks.Add
Const xlExcel4MacroSheet=3
Set Sheet=Book.Worksheets.Add(,,,xlExcel4MacroSheet)
Sheet.Cells(1,1)="=ALERT(1)"
Sheet.Cells(2,1)="=RETURN()"
Call Application.Run(Sheet.Name & "!A1")
Book.Saved=True
Book.Close
Application.Quit

「Excelマクロ使い」なら、もっといろいろなことができるのかも。

2008年3月21日 (金)

文字列sの右端からn文字を削除する。

複文でよいなら、

n = Len(s) - n
If n < 0 Then n = 0
s = Left(s, n)

ですが、これをひとつの式でやるには?

△ s = Left(s, Len(s) - Left(s, n))

△ s = Left(s, Len(Mid(s, n + 1)))

○ s = Left(s, Len(s) - n And Len(s) > n)

△ s = Left(s, Array(Len(s) - n, 0)((Len(s) > n) + 1))

性能的には、文字列操作などが少ない、3番目がよいでしょう。

2008年3月20日 (木)

?:条件演算子の代替式(その2)

式1 ? 式2 : 式3 は、式2、式3が数値なら、式2 And 式1 Or 式3 And Not 式1 と書けますが、数値でない場合は?

Array(式2, 式3)(式1 + 1)

ただし、式1は、Booleanです。

2008年3月19日 (水)

Min()関数やMax()関数、?:条件演算子の代替式

VBScriptやVBAには、Min()関数やMax()関数がありません。
関数を作るか、If文などで代替できますが、これをひとつの式でやるには?
JScriptなら、式1 ? 式2 : 式3 のような式が書けますが。。。

Max=x And x>y Or y And Not x>y

Min=x And Not x>y Or y And x>y

つまり、式1 ? 式2 : 式3 は、式2 And 式1 Or 式3 And Not 式1 と書きます。
ただし、式1は、Booleanです。

2008年3月18日 (火)

アプリの入出力パラメタ

普通のアプリでは、以下の順に入出力パラメタを考えます。

入力パラメタ
1.引数
2.環境変数
3.標準入力

出力パラメタ
1.終了コード
2.環境変数(※)
3.標準出力、標準エラー

ところが、ちょっと変わったアプリ、例えば、Excelファイルなどでは、これが忘れ去られてしまうようです。
確かに、1は無理ですが、2や3なら可能です。

※ 同一インスタンス内で別のExcelファイルに渡すような場合。

2は、VBAのEnviron("名前")やWScript.ShellのEnvironment("Process").Item("名前")を使用します。
3は、Scripting.FileSystemObjectのGetStandardStream({0|1|2})を使用します。
3の親側は、WScript.ShellのExec().{StdIn|StdOut|StdErr}を使用します。

2008年3月17日 (月)

半角か?、全角か?、はたまた、シフトJISにない文字か?

所謂、1バイト文字、半角文字を
ASCII + 半角カタカナ
とすれば、以下で得られます。

If 0 <= AscW(c) And AscW(c) <= 127 Or &Hff61 <= AscW(c) And AscW(c) <= &Hff9f Then '半角文字

シフトJIS = ASCII + 半角カタカナ + JIS漢字
とすれば、所謂、2バイト文字、全角文字は、
JIS漢字 = シフトJIS - ASCII - 半角カタカナ
で得られます。

If Chr(Asc(c))<>c Then 'シフトJISにない文字
ElseIf 0 <= AscW(c) And AscW(c) <= 127 Then 'ASCII
ElseIf &Hff61 <= AscW(c) And AscW(c) <= &Hff9f Then '半角カタカナ
Else
'全角文字
End If

2008年3月16日 (日)

シフトJISにない文字を判定する。

シフトJISにない文字は以下で判定できます。

If Chr(Asc(c))<>c Then 'シフトJISにない文字

ただし、ロカールは"ja"の場合です。
同様に、ロカールを変えれば、その文字集合にない文字を判定できます。

このように、VBScriptのAsc()/Chr()は、ロカールに依存します。
一方、FileSystemObjectのTextStreamは、ロカールに依存しないようです。

2008年3月14日 (金)

半角カタカナ文字を判定する。

半角カタカナの文字コードは、シフトJISで、a1 - df、Unicodeで、ff61 - ff9f なので、その判定方法は、

△ If &Ha1 <= Asc(c) And Asc(c) <= &Hdf Then '半角カタカナ

または、

○ If &Hff61 <= AscW(c) And AscW(c) <= &Hff9f Then '半角カタカナ

ここで、もし、その文字が欧文文字で、かつ、ロカールが欧米諸国の場合、Asc(c)で判定すると、欧文文字が半角カタカナに誤判定される可能性があります。
例えば、Áは"en-us"でc1、チは"ja"でc1になります。
なので、文字はUnicodeのまま、AscW(c)で判定したほうがよいでしょう。

2008年3月13日 (木)

ASCII文字を判定する。

ASCII文字の文字コードは、0 - 127 なので、その判定方法は、

× If 0 <= Asc(c) And Asc(c) <= 127 Then 'ASCII

または、

○ If 0 <= AscW(c) And AscW(c) <= 127 Then 'ASCII

ここで、もし、その文字がシフトJISにない場合、Asc(c)で判定すると、Asc(c)=63、"?"に変換されて、ASCIIに誤判定されてしまいます。
なので、文字はUnicodeのまま、AscW(c)で判定すべきです。

2008年3月12日 (水)

配列をシャッフルする。

VBAとVBScriptで、これが一番簡単。

Sub Shuffle(a)
Dim k, j As Long
Dim t
Randomize
For k = UBound(a) To 0 Step -1
  j = Fix(Rnd * (k + 1))
  t = a(j)
  a(j) = a(k)
  a(k) = t
Next
End Sub

Dim a
Dim k As Long
a = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Call Shuffle(a)
For k = 0 To UBound(a)
  Debug.Print a(k)
'  WScript.Echo a(k)
Next

2008年3月10日 (月)

VBAのDir()関数のワイルドカードは誤動作する。

Dir("*1.txt") のようなワイルドカードを指定すると、"*1.txt" でないファイルも拾います。
これは、Dir()が短いファイル名の~1などを拾うからです。

Dim Filename As String
Filename = Dir("*1.txt")
Do While Len(Filename)
  Debug.Print Filename
  Filename = Dir()
Loop

Dir()の障害のような気がしますが、これは仕様と諦めて、If ~ Like "*1.txt" Then などで二重にチェックするとよいでしょう。

Dim Filename As String
Filename = Dir("*1.txt")
Do While Len(Filename)
  If Filename Like "*1.txt" Then
    Debug.Print Filename
  End If
  Filename = Dir()
Loop

2008年3月 9日 (日)

VBAで文字列の中身をダンプする。

VBAで文字列の中身をダンプする。

文字列の中に変な文字コードがないかは、VBScriptやJScriptでは、WScript.Echo(escape(文字列))で、確認するのですが、VBAではどうするか?
ScriptControl経由でVBScriptやJScriptのescape()を使うこともできますが、それより、以下のような関数を作って使ったほうが簡単でしょう。

Sub Dump(Text As String)
Dim k As Long
For k = 1 To Len(Text)
Debug.Print k, Mid(Text, k, 1), Hex(Asc(Mid(Text, k, 1)))
Next
End Sub

MsgBoxに出すなら、

Sub Dump(Text As String)
Dim k As Long
Dim a() As String
ReDim a(Len(Text) - 1)
For k = 1 To Len(Text)
a(k - 1) = Join(Array(k, Mid(Text, k, 1), Hex(Asc(Mid(Text, k, 1)))), vbTab)
Next
MsgBox Join(a, vbLf)
End Sub

2008年3月 7日 (金)

ERRORLEVELを返さないコマンドのエラー判定

DELコマンドは、エラーになってもERRORLEVELを返しません。
その代わりに標準エラーにメッセージが出ます。
なので、その有無を判定すればよいでしょう。

DEL A 2>&1 | FIND /V ""

で、ERRORLEVELは、エラーがあれば、0、なければ、1になります。逆ですが:-p

CMD/CEXIT 0
FOR /F "delims=" %2 IN ('"DEL A 2>&1"') DO CMD/CEXIT 1 & ECHO %2

とすれば、ERRORLEVELは、エラーがなければ、0、あれば、1になります。面倒ですが:-(

2008年3月 5日 (水)

SETLOCAL ~ ENDLOCAL内部の環境変数をエクスポートする。(その2)

前回記事では、

ENDLOCAL & SET X=%X%

で、環境変数をエクスポートしましたが、この方法は、複文(~)の中では使えません。

そこで、代わりに、FOR変数を使います。

(
set a=
setlocal enabledelayedexpansion
set a=aa^<a
for /f "delims=" %%a in ("!a!") do endlocal & set a=%%a
cmd /v:on /c echo !a!
)

2008年3月 4日 (火)

バッチファイルでInStrRev(文字列1,文字列2)擬似

文字列1 の中から指定された文字列2 を最後の文字位置から検索を開始し、最初に見つかった文字位置(1~)を返します。
見つからないときは、0 です。

@echo off
setlocal enabledelayedexpansion

set x=abcd^<e
set y=c
call :instrrev
echo !r!
goto :eof

rem r=len(x)
:len
set /a r=0
:len2
(set z=!x:~%r%,1!)
if not defined z goto :eof
set /a r+=1
goto :len2

rem r=rev(x)
:rev
(set r=)
set /a n=0
:rev2
(set z=!x:~%n%,1!)
if not defined z goto :eof
(set r=!z!!r!)
set /a n+=1
goto :rev2

rem r=instrrev(x,y)
:instrrev
setlocal enabledelayedexpansion
call :rev
set xx=!r!
set x=!y!
call :rev
set yy=!r!
set x=!xx:*%yy%=!
call :len
set /a zlen=r
if !zlen!==!xlen! (set /a r=0) else (set /a r=zlen + 1)
endlocal & set r=%r%

2008年3月 3日 (月)

バッチファイルで文字列を反転する。

文字列 ABC を CBA のように反転します。

@echo off
setlocal enabledelayedexpansion

set x=abcd^<e
call :rev
echo !r!
goto :eof

rem r=rev(x)
:rev
(set r=)
set /a n=0
:rev2
(set z=!x:~%n%,1!)
if not defined z goto :eof
(set r=!z!!r!)
set /a n+=1
goto :rev2

これができると、InStrRev(文字列1,文字列2) ができます。

2008年3月 2日 (日)

バッチファイルでInStr(文字列1,文字列2)擬似

文字列1 の中から指定された文字列2 を検索し、最初に見つかった文字位置(1~)を返します。
見つからないときは、0 です。

@echo off
setlocal enabledelayedexpansion

set x=abcd^<e
set y=c
call :instr
echo !r!
goto :eof

rem r=len(x)
:len
set /a r=0
:len2
(set z=!x:~%r%,1!)
if not defined z goto :eof
set /a r+=1
goto :len2

rem r=instr(x,y)
:instr
setlocal enabledelayedexpansion
set xx=!x!
call :len
set /a xlen=r
set x=!y!
call :len
set /a ylen=r
set x=!xx:*%y%=!
call :len
set /a zlen=r
if !zlen!==!xlen! (set /a r=0) else (set /a r=xlen - ylen - zlen + 1)
endlocal & set r=%r%

2008年3月 1日 (土)

バッチファイルで文字列の長さを得る。

文字列操作は、まず、文字列の長さを得ることです。

@echo off
setlocal enabledelayedexpansion

set x=abcd^<e
call :len
echo !r!
goto :eof

rem r=len(x)
:len
set /a r=0
:len2
(set z=!x:~%r%,1!)
if not defined z goto :eof
set /a r+=1
goto :len2

これが出来れば、InStr(string1, string2) も出来ます。

« 2008年2月 | トップページ | 2008年4月 »