いりや さん 2004年 10月 11日 14時 06分 49秒

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

| ばんのしゃーによかばんた さん 2004年 10月 10日 18時 15分 11秒
|
| >いりや さん 2004年 10月 09日 20時 44分 59秒
| >むしろ、to be tolerant を「そのプログラムは大丈夫走り続ける」
| >と意訳する話の方が私にとっては新鮮でした。初めてです。この解
| >釈は。
|
| 昔、国産のFault Tolerant OSを作っていまいした。主な特徴は、
| 無停止(Non Stop 24h/365日連続運転)
| 耐故障(FT[Fault Tolerant])、
| 並列(Parallel、NUMA[Non Uniform Memory Access])

Fault Tolerant の tolerant でしたか。ようやく解釈の背景情報がわかったよ
うな気がします。この定義で free(3c) を読むとピンとこないですね。

いりや さん 2004年 10月 11日 02時 21分 54秒

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

| >いりや さん 2004年 10月 09日 20時 21分 46秒
| >どういう形で試されましたか。fileDeletion1() ? fileDeletion2() ?
|
| ファイル数が1M個のフォルダはなかったので、
|
| var folderpath = 'c:\\windows\\i386';
|
| ファイル数が約5K個のフォルダが200個あるとして、
|
| var files = new Enumerator(FileSystemObject.getFolder(folderpath).files).asArray();
| for(var k=1;k<200;k++){
| var files2 = new Enumerator(FileSystemObject.getFolder(folderpath).files).asArray();
| var files = files.concat(files2);
| }
| var targets = files.select_(discriminator);
|
| それらをコンカチしました。

Enumerator.prototype.asArray() は、Array を生成して ICollection インター
フェイスを持つコレクションの要素をすべて数え上えあげてそれを値にセットし
て返します。ですので指定個数の Array の作成のためにそれ以外の Array の作
成をなくすのならば以下のようにしてはいかがでしょうか。これで files
(Array) を準備するための費用は Array.prototype.push() の費用が要素数で一
定であると仮定すると O(n) になると思います。

(function () {
    var $ = Enumerator.prototype;
    $.do_ = function (operation) {
        for (; !this.atEnd(); this.moveNext())
            operation(this.item());
        this.moveFirst();
    }
})();

(function () {
    var $ = Number.prototype;
    $.timesRepeat_ = function (operation) {
        for (var i = 0; i < this; i++)
            operation();
    }
})();

(function () {
    var $ = Array.prototype;
    $.do_ = function (operation) {
        for (var i = 0; i < this.length; i++)
            operation(this[i]);
    }
    $.select_ = function (discriminator) {
        var anArray = new Array();
        this.do_(function (each) { if (discriminator(each)) anArray.push(each) });
        return anArray;
    }
})();

var FileSystemObject = new ActiveXObject('Scripting.FileSystemObject');
var folderpath = 'c:\\windows\\system32';
var enumerator = new Enumerator(FileSystemObject.getFolder(folderpath).files); // 2,000 files
var files = new Array();
var n = 500;
n.timesRepeat_(function () {
    enumerator.do_(function (each) { files.push(each) });
});
// files : 2,000 * 500 = 1,000,000 (200Mbytes 程度消費)

ところで [B] : 部分ごとに逐次に処理する、を選択するならば、
Enumerator.prototype.do_() のように要素を取り出す費用を都度支払って処理
を進めればよいでしょう。

var FileSystemObject = new ActiveXObject('Scripting.FileSystemObject');
var folderpath = 'd:\\windows\\system32';
var enumerator = new Enumerator(FileSystemObject.getFolder(folderpath).files);

enumerator.do_(function (file) {
    if (/^[aA]/.test(file.name)) {
        doSomethingWith(file);
    }
});

つちや さん 2004年 10月 10日 21時 58分 37秒

> ただし、
> >Const adInteger = 3
> は、
> Const adDouble = 5
> を使わないと、時刻が消えますよ。

その通りです。失礼しました。

> ソートには、同値キーの順序が保存される/ないものがありますが、
> 保存されるほうが好きです。JScriptやADOは保存されるようです。
> これは好みだけでなく、ソート結果の比較がし易いなど、実利もあります。
> ヒープソートは保存されないようです。所謂、高速ソートはその傾向でしょうか。
> 高速性とのトレードオフになっているのでしょうか。

保存される方を安定したソートというわけですが、高速ソートの中ではマージソートがそうですね。
で、さっそくVBScriptでマージソートを。

Sub sortMergeSub(ByRef a(), ByVal p, ByVal q, ByRef w())
c = (p + q) \ 2

If p < c Then
Call sortMergeSub(a, p, c, w)
End If

If c + 1 < q Then
Call sortMergeSub(a, c + 1, q, w)
End If

i = p
j = c + 1
For k = 0 To q - p
If i <= c And j <= q Then
If CompareAB(a(i),a(j)) < 0 Then
m = True
Else
m = False
End If
Else
If i <= c Then
m = True
Else
m = False
End If
End If
If m Then
w(k) = a(i)
i = i + 1
Else
w(k) = a(j)
j = j + 1
End If
Next

For k = 0 To q - p
a(k + p) = w(k)
Next

End Sub

Sub sortMerge(ByRef a)
If 0 < UBound(a) Then
ReDim w(UBound(a))
Call sortMergeSub(a, 0, UBound(a), w)
Erase w
End If
End Sub

Function CompareAB(A,B)
If IsArray(A) Then
If A(0) < B(0) Then
CompareAB = -1
ElseIf A(0) > B(0) Then
CompareAB = 1
Else
CompareAB = 0
' If A(1) < B(1) Then '第2列でもソートする場合
' CompareAB = -1
' ElseIf A(1) < B(1) Then
' CompareAB = 1
' Else
' CompareAB = 0
' End If
End If
Else
If A < B Then
CompareAB = -1
ElseIf A > B Then
CompareAB = 1
Else
CompareAB = 0
End If
End If
End Function

'テスト用データ
n=10000
ReDim Data(n-1)
For i = 0 To UBound(Data)
Data(i) = CLng(Int(Rnd(1) * 100))
Next

ta = Timer()
Call sortMerge(Data)
tb = Timer()

MsgBox "処理時間: " & ((tb - ta) * 1000)

いりや さん 2004年 10月 10日 19時 46分 44秒

URL は、

[[iriyak:JScript:DateLastModifiedでファイル名をソート]]
http://iriyak.adam.ne.jp/wiliki/uwsc.cgi?iriyak%3aJScript%3aDateLastModified%a4%c7%a5%d5%a5%a1%a5%a4%a5%eb%cc%be%a4%f2%a5%bd%a1%bc%a5%c8&l=jp

[[iriyak:JScript:DateLastModifiedでファイル名をソートvol2]]
http://iriyak.adam.ne.jp/wiliki/uwsc.cgi?iriyak%3aJScript%3aDateLastModified%a4%c7%a5%d5%a5%a1%a5%a4%a5%eb%cc%be%a4%f2%a5%bd%a1%bc%a5%c8vol2&l=jp

です。

いりや さん 2004年 10月 10日 19時 34分 56秒

いりやです。

| いりや さん 2004年 10月 09日 18時 07分 16秒
[snip]
| 皆さん、色々と有意義な話題を提供くださってありがとうございま
| す。WiLiKi に自分の検証結果をまとめてみました。
|
| [[iriyak:JScript:DateLastModifiedでファイル名をソート]]
| http://iriyak.adam.ne.jp/wiliki/uwsc.cgi?iriyak%3aJScript%3aDateLastModified%a4%c7%a5%d5%a5%a1%a5%a4%a5%eb%cc%be%a4%f2%a5%bd%a1%bc%a5%c8&l=jp
|
| 要約すると次の通りでした。
|
| 配列要素数の差 (に連動する比較回数の差) と関数オブジェクト呼
| び出し費用の合算で性能差が生まれていた。

ソートの部分の費用を遅いマシンで測定してみた結果を vol2 としてまとめまし
た。

・プログラムの処理全体では 6.3 〜 6.6 倍の差

・Array.prorotype.sort() のコンパイルコードと function (a, b) { return a.dateLastModified - b.dateLastModified }
 関数オブジェクト呼び出し費用の差は、大体 288.05 倍くらい

今回の処理全体のプロファイルから (ソートの) 比較の単位費用がその他の格納
/印刷に対して大きくなかったため、288.05 倍の差が 6.6 倍の差にまでおさえ
られていました。

そうではなくてソートの費用が処理全体のほとんどを占める場合は 288.05 倍の
差がそのまま見えてくるでしょうね。

また、この追試験の結果から、配列要素数の差に連動する比較回数の差は、
DateLastModified のばらつき度によってもかわることがわかりました。試験環
境をかえてそこにもパラメータがあることに気づきました。よくよく考えてみれ
ばそうだった。

ばんのしゃーによかばんた さん 2004年 10月 10日 18時 15分 11秒

>いりや さん 2004年 10月 09日 20時 44分 59秒
>むしろ、to be tolerant を「そのプログラムは大丈夫走り続ける」
>と意訳する話の方が私にとっては新鮮でした。初めてです。この解
>釈は。

昔、国産のFault Tolerant OSを作っていまいした。主な特徴は、
無停止(Non Stop 24h/365日連続運転)
耐故障(FT[Fault Tolerant])、
並列(Parallel、NUMA[Non Uniform Memory Access])

普通のOSはアプリが死んでもOSは動き続ける。ですが、
このFT-OSでは、OS(現用)空間が死んでも、別のOS(待機)空間に、
やりかけの仕事を引き継いで、アプリに気付かせずに動き続ける。
複数あるPM(Processor Module=CPU+Memoryのボード)のひとつが死んでも、
残りのPMに、やりかけの仕事を引き継いで、動き続ける。
全系がいったん死んでも、立ち上げ直して、やりかけの仕事を引き継いで、
動き続ける。それが、失敗したら、もう一度、引き継ぎ範囲を絞って、
立ち上げ直す。というふうに、とってもしつこいのです。

fault tolerantはerror detectionとは違う概念で、
>| which is designed to be tolerant against simple errors,
は、
which is designed to detect earlier simple errors,
のほうが、ぴったりなように思います。

ばんのしゃーによかばんた さん 2004年 10月 10日 18時 13分 36秒

>いりや さん 2004年 10月 09日 20時 21分 46秒
>どういう形で試されましたか。fileDeletion1() ? fileDeletion2() ?

ファイル数が1M個のフォルダはなかったので、

var folderpath = 'c:\\windows\\i386';

ファイル数が約5K個のフォルダが200個あるとして、

var files = new Enumerator(FileSystemObject.getFolder(folderpath).files).asArray();
for(var k=1;k<200;k++){
var files2 = new Enumerator(FileSystemObject.getFolder(folderpath).files).asArray();
var files = files.concat(files2);
}
var targets = files.select_(discriminator);

それらをコンカチしました。

ばんのしゃーによかばんた さん 2004年 10月 10日 16時 41分 45秒

何もNotePadに凝っているわけでは全くないのですが、

!!!重要!!!
改行が CR+CR+LF のファイルを編集保存すると、改行が消えてなくなります。

これはちょっと問題です。修復の手間を考えるとデータ破壊に近いことになります。
NotePadで編集保存する場合はバックアップを取りましょう。なんて冗談がきついなぁ。

※※※

スクリプト類がないはずのHTMLファイルなのに、情報バーが出るので、
何かいなと、HTMLファイルをNotePadでちょっと編集して保存したら、
1行おきの間延びしたソースリストが改行なしに変化してしまいました。
一体何が起きたのか?と調べたら、そういうことだったのです。

※※※

また、情報バーも、何を検出したのか、具体的に教えて欲しいものです。
今回は、サーバか誰かがHTMLファイルの末尾に自動生成する?、
</object></script></applet>類が、誤って?、引っ掛かったのでした。

※※※

CR+CR+LF の改行は異常ですが、これがどうしてできるのか。

unix2dosのようなunixの改行(LF)をDOSの改行(CR+LF)に変換する処理を二重に通した?
※SFU(Services for Unix)のunix2dos.exeは二重に通ししてもOK。

WSH2.0のWScript.Echoには、CR+LFをCR+CR+LFに変換する障害があります。
※WSH5.6は修正済み。

ばんのしゃーによかばんた さん 2004年 10月 10日 16時 41分 09秒

準備運動が出来たところで、
VBScriptでIEをevent handler付きでClass化してみました。

Class内から、executeGlobalで、global contextに、
instanceごとに別々のevent handlerを定義し、
instance自身のオブジェクト参照をglobalな配列変数に入れて、
各event handlerから自身のinstanceを参照するところが味噌です。

――――――――――――――――――――――――――――――――――――――
Option Explicit

Class InternetExplorer
Public index
Public onquit
Public ie
Private Sub Class_Initialize()

ExecuteGlobal "" & vbCRLF & _
"Dim global_ie" & vbCRLF & _
""
If IsEmpty(global_ie) Then global_ie=array()
index=UBound(global_ie)+1
ReDim Preserve global_ie(index)
Set global_ie(index)=Me

ExecuteGlobal "" & vbCRLF & _
"Sub IE" & index & "_OnQuit()" & vbCRLF & _
"MsgBox ""onquit " & index & """" & vbCRLF & _
"global_ie(" & index & ").onquit=True" & vbCRLF & _
"End Sub"

Set ie=WScript.CreateObject("InternetExplorer.Application","IE" & index & "_")
ie.Visible=True
ie.Navigate "about:blank"
Do While ie.Busy Or ie.ReadyState<>4
WScript.Sleep 100
Loop
End Sub

Private Sub Class_Terminate()
If Not onquit Then ie.quit
End Sub
End Class

Dim ies(1)
Set ies(0)=New InternetExplorer
msgbox ubound(global_ie)
Set ies(1)=New InternetExplorer
msgbox ubound(global_ie)

Do While Not ies(0).onquit Or Not ies(1).onquit
WScript.Sleep 100
Loop
WScript.Quit

ばんのしゃーによかばんた さん 2004年 10月 10日 16時 40分 35秒

準備運動123。

俺俺詐欺に注意! 俺って誰? 私は誰? Meって誰? 

曖昧Meはよくない。ということで、
――――――――――――――――――――――――――――――――――――――
class a
sub class_initialize()
wscript.echo "class",typename(me)
executeGlobal "wscript.echo ""executeGlobal"",typename(me)"
wscript.echo "go",typename(go)
end sub
end class

wscript.echo "main",typename(me)
set go=me
set x=new a
――――――――――――――――――――――――――――――――――――――
を実行すると、
――――――――――――――――――――――――――――――――――――――
main VBScriptTypeInfo
class a
executeGlobal a
go VBScriptTypeInfo
――――――――――――――――――――――――――――――――――――――
という結果になります。

また、
――――――――――――――――――――――――――――――――――――――
Sub b()
a.WScript.Echo a.c
End Sub
Set a=Me
c="!c!"
Me.b()
――――――――――――――――――――――――――――――――――――――
てなことも。

VBでは、同名の関数を作っても、メンバ修飾で区別できますが、
VBA.Strings.StrConv
VB.Clipboard
同様なことを、VBSで出来ないものでしょうかねぇ。

classからglobal contextへの変数の追加は、こんな風に。
――――――――――――――――――――――――――――――――――――――
Option Explicit
class a
sub class_initialize()
executeGlobal "dim b"
b=i
i=i+1
end sub
end class

dim i
dim x,y
i=0
set x=new a
wscript.echo b
set y=new a
wscript.echo b
――――――――――――――――――――――――――――――――――――――
二重定義エラーにならないですね。
あとは、配列だ。

ばんのしゃーによかばんた さん 2004年 10月 10日 16時 39分 46秒

>つちや さん 2004年 10月 08日 21時 09分 33秒
>面白そうということで、ファイル一覧ソートに私も参加。(そういう企画じゃなかったかな)
>つかのぺさんのとこにあるVBScriptのクイックソートはかなり速いですが、今回はADOを使って。
>自分でわかりやすくて、応用がきくもので。

2.9秒でした。やりますね。

ただし、
>Const adInteger = 3
は、
Const adDouble = 5
を使わないと、時刻が消えますよ。

>つちや さん 2003年 07月 13日 03時 52分 56秒
>VBSは自前のソートを持っていないので、とりあえず、関数を作ってソートする例です。
のヒープソートだと、

2.4秒でした。これには負けましたね。

※※※

ソートには、同値キーの順序が保存される/ないものがありますが、
保存されるほうが好きです。JScriptやADOは保存されるようです。
これは好みだけでなく、ソート結果の比較がし易いなど、実利もあります。
ヒープソートは保存されないようです。所謂、高速ソートはその傾向でしょうか。
高速性とのトレードオフになっているのでしょうか。

※※※

ソートと言うと、何ソートが速い、と、ソートアルゴリズムばかりが注目されますが、
それよか、比較の重さ、データ持ち回りの重さのほうを注意すべきです。
これらを出来るだけ軽くすることが重要です。


いりや さん 2004年 10月 09日 21時 17分 30秒

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

| ばんのしゃーによかばんた さん 2004年 10月 05日 22時 13分 17秒
|
| >いりや さん 2004年 10月 03日 20時 16分 23秒
| >これは契約によるプログラミングに出てくる事前条件の満足に通じ
| >るものがありますね。
|
| これは、インタフェース境界でのパラメタチェックの話でしょうか。
| ちゃんとやろうとすると、これがまた、なかなか大変ですよね。
| なので入口チェックだけでなく、処理中チェックも欠かせません。

そうです。この条件を満足してくれればこの仕事を請け負う、その
条件を明記したものです。例えば青木淳さんの本に紹介された
(Model-View-Controller パタンの) ある View のあるメソッドの
仕様を引用します。

on: aModel get: getSymbol put: putSymbol valueMinMaxDivideRound: anArray

事前条件

  Assertion requireThat: getSymbol isInstanceOf: Symbol.
  Assertion requireThat: putSymbol isInstanceOf: Symbol.
  Assertion requireThat: anArray obeyTheConstraint: [anArray size = 4].
  Assertion requireThat: anArray obeyTheConstraint:
  [ | min max div rnd |
  min := anArray at: 1. max := anArray at: 2.
  div := anArray at: 3. rnd := anArray at: 4.
  (max > min and: [div > 1]) and: [rnd > 0 and: [rnd < (max - min)]]]


| >私は Bertrand Meyer さんのオブジェクト指向入門を読んで表明
| >(Assertion) などの必要なキーワードを知りました。
| >表明そのものは Jon L. Bentley さんのプログラマのうちあけ話の
| >アルゴリズムの検査や XP だっけか、単体検査の枠組みでも導入さ
| >れていますね。
|
| よくあるのは、C の assert() macroをソースに仕込んでおいて、
| テスト時だけ有効にすることですが、それではいけません。
| 本番運用時こそ、正しく動いていることを担保しなくては。

このあたり製造案件のプロジェクトの開発標準で指定されていない
と、表明を積極的に利用しているソースコードになる確率はかぎり
なく低いですね。それにくらべて例外のハンドリングは構文に取り
入れられているためか身近に見れるようにはなりましたが。あっこ
れは Java の話です。

[ Reference ]

青木淳さん, 例題による!!オブジェクト指向分析設計テクニック
http://www.src-j.com/BOOK_NO/032.htm
http://www.sra.co.jp/people/aoki/htmls/Book2.html

いりや さん 2004年 10月 09日 20時 47分 27秒

つちやさん、

| ちなみに、私がFDateフィールドをDateではなくIntegerタイプにし
| たのは、Integerにした方が体感できるほど速かったからなのでし
| た。ご参考まで。

ソートの結果が他の方式と一緒にならなくはありませんでしたか??
もともと手を入れるきっかけになったのはソートの結果が方式で整
合がとれなかったものですから・・・。

いりや さん 2004年 10月 09日 20時 44分 59秒

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

| ばんのしゃーによかばんた さん 2004年 10月 06日 19時 57分 33秒
|
| >ばんのしゃーによかばんた さん 2004年 10月 03日 18時 28分 09秒
| >蛇の道は蛇。OS屋さんの考えそうなことを想像すると、
[snip]
| >| Recent versions of Linux libc (later than 5.4.23) and GNU
| >| libc (2.x) include a malloc implementation which is tun-
| >| able via environment variables. When MALLOC_CHECK_ is
| >| set, a special (less efficient) implementation is used
|
| この文は、ここまではいいけど。この後はなんか変ですね。
|
| >| which is designed to be tolerant against simple errors,
| >| such as double calls of free() with the same argument, or
| >| overruns of a single byte (off-by-one bugs).
|
| simple errorsしても、そのプログラムは大丈夫走り続ける。
| と言っているようですけど、それは、誤解で、真意は、
| simple errorsをdetectして、そのプログラムはabortさせる。
| だから、システム全体としては大丈夫と言っている。
| のではありますまいか。原文が悪いのか、英文解釈が悪いのか、
| 分かりませんが。

to be tolerant にどこまで厳密な定義が与えられるか、その定義
がここで与えられていない状況においては変とは思いません。
NOTES に仕様の説明として to be tolerant と書くことは望ましい
かという観点ではもう少し言葉を足して欲しい気持ちはあります。
未定義の振る舞いとはいえ。

むしろ、to be tolerant を「そのプログラムは大丈夫走り続ける」
と意訳する話の方が私にとっては新鮮でした。初めてです。この解
釈は。

まぁ、真意はソースコードにあり。なのでソースコードをみていこ
うと思っています。

つちや さん 2004年 10月 09日 20時 23分 52秒

拝見しました。細かい検証ご苦労さまです。
ちなみに、私がFDateフィールドをDateではなくIntegerタイプにしたのは、Integerにした方が体感できるほど速かったからなのでした。ご参考まで。

いりや さん 2004年 10月 09日 20時 21分 46秒

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

| ばんのしゃーによかばんた さん 2004年 10月 09日 15時 53分 35秒
|
| >いりや さん 2004年 08月 13日 14時 05分 40秒
| のスクリプトで試してみると、
| file数 ElapsedTime
| 5K 4.40Sec
| 50K 44.7
| 150K 158(2m38s)
| 1M 2483(41m23s)
|
| 10K(万)のorderまではlinearですが、
| 100K(十万)のorderから非線形になっていくようです。
| M(百万)では数倍に。

どういう形で試されましたか。fileDeletion1() ? fileDeletion2() ?
[A] か [B] かという議論と、私のスクリプトの実行結果が非線形に
なっていく話がどう関係しているのか文脈からわからなかったのでその
ヒントがプログラムに隠されているとおもい、おききしています。

いりや さん 2004年 10月 09日 18時 07分 16秒

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

| ばんのしゃーによかばんた さん 2004年 10月 08日 17時 05分 08秒
|
| >いりや さん 2004年 10月 06日 12時 34分 12秒
| >ソート関数の引数に要素を比較する関数オブジェクトを与えて実現
| >できるとおもいます。以下サンプルです。
|
| C:\windows\system32で昇順で試しますと15.8秒でした。
|
| やはり、性能上の所謂ホットスポットである比較関数で、処理の重い、
| オブジェクト参照するのが、構造的によくないのではないかと思います。
| >var discriminator1 = function discriminator1 (a, b) { return a.dateLastModified - b.dateLastModified };

| つちや さん 2004年 10月 08日 21時 09分 33秒
|
| 面白そうということで、ファイル一覧ソートに私も参加。(そういう企画じゃなかったかな)
| つかのぺさんのとこにあるVBScriptのクイックソートはかなり速いですが、今回はADOを使って。自分でわかりやすくて、応用がきくもので。

皆さん、色々と有意義な話題を提供くださってありがとうございま
す。WiLiKi に自分の検証結果をまとめてみました。

[[iriyak:JScript:DateLastModifiedでファイル名をソート]]
http://iriyak.adam.ne.jp/wiliki/uwsc.cgi?iriyak%3aJScript%3aDateLastModified%a4%c7%a5%d5%a5%a1%a5%a4%a5%eb%cc%be%a4%f2%a5%bd%a1%bc%a5%c8&l=jp

要約すると次の通りでした。

配列要素数の差 (に連動する比較回数の差) と関数オブジェクト呼
び出し費用の合算で性能差が生まれていた。

いりや

追伸 つちやさん、ADODB.Recordset は今日初めて msdn を見なが
ら JScript にポーティングしました。若干ポーティングにあたっ
て修正を施しています。よろしければご確認ください。

ばんのしゃーによかばんた さん 2004年 10月 09日 15時 53分 35秒

scalabilityの話題です。

計算量が非線形(n**2のorder)だと、当然scalabilityが問題になりますが、
仮令、線形であってもscalabilityが問題になることがあります。

>管理人むたぐち さん 2003年 07月 07日 18時 43分 36秒
>> ワイルドカード
>再帰的にフォルダを検索して、全ファイル・フォルダのフルパスを格納、
>それに対して検索式と逐一チェックさせるというのは、もっとも簡単な処理ですよね。

>いりや さん 2004年 08月 13日 14時 05分 40秒
>件名: JScript で File>>delete() を実行できない
>var files = new Enumerator(FileSystemObject.getFolder(folderpath).files).asArray();
>var targets = files.select_(discriminator);

についても、scalabilityが気になります。

一般に、プログラムの戦略として、
[A] 全体を一括して処理する。
[B] 部分ごとに逐次に処理する。
の二つが考えられます。

例えば、テキストストリームなら、
[A] ReadAll
[B] Do While Not AtEndOfStream:ReadLine:Loop

unixのsedやawkなどのフィルタは[B]
[B]は、scalability(性能/規模)の心配はありません。

[A]は、注意が必要です。
全体をメモリに展開できるか。
メモリ空間に収まらなければ、エラーになります。
実メモリに収まるなら、快適に処理できます。
実メモリに収まらなければ、ページスワップが発生します。少し遅い。
少なくともワーキングセットは実メモリに収まっているか。
でなければ、ページスラッシングが発生します。めちゃ遅い。

あるODBMS(Object Data Base Management System)で、ちょっと大きいクラス
(数百万インスタンス)の全件を処理しようとして、オブジェクト参照が
パンクしたり、性能が極端に低下したことがあります。
全件(広域)処理では、オブジェクト参照を積極的に解放する必要があります。

ネットワークドライブやプリンタ、shell.Windowsなどは、高が知れています。
しかし、filesはどうでしょう。
filesは[B]が適しているのではないでしょうか。
だからこそ、
For Each file In Files:file.Delete:Next
も安全に出来るようにしているのではないか、と思います。

>いりや さん 2004年 08月 13日 14時 05分 40秒
のスクリプトで試してみると、
file数 ElapsedTime
5K 4.40Sec
50K 44.7
150K 158(2m38s)
1M 2483(41m23s)

10K(万)のorderまではlinearですが、
100K(十万)のorderから非線形になっていくようです。
M(百万)では数倍に。

以前なら、普通の環境で、有り得なかったファイル数でしょうが、
今は、ディスク容量の数十GBは普通ですから、1ディスク数M(百万)ファイルも
ありふれたシチュエーションとして考慮しなければなりません。

一般に、ソフト開発では、こういう大規模数量の性能に注意しましょう。
意識して顕在化させないと、やわな負荷テストではすり抜けてしまいます。
また、作る前に、[A][B]どちらの戦略を採るべきかをよく検討しましょう。

中小規模で性能に有効なバッファリングやキャッシュのような戦術は、
大規模では無力化するだけでなく、かえって性能劣化要因になったり、
障害になったりもします。そういう観点での検討も必要です。

ばんのしゃーによかばんた さん 2004年 10月 09日 15時 52分 48秒

Windows XPで、メモ帳で編集を終えて保存しようとすると、以下がよく出ます。

---------------------------
メモ帳
---------------------------
メモリ不足のためこの操作を実行できません。Windows アプリケーションをいくつか終了して空きメモリ領域を増やしてから、再実行してください。
---------------------------
OK
---------------------------

OKすれば保存されて、特に問題なさそうなんですが、何でしょう。

他に動かしているものはToClip.HTAくらいなものなんですが、
mshta.exeってメモリ喰いなんでしょうか。

タスクマネジャで見るとexplorer.exeより少し多いくらいなんですが。

ばんのしゃーによかばんた さん 2004年 10月 09日 15時 52分 06秒

>ばんのしゃーによかばんた さん 2004年 10月 07日 17時 07分 07秒
>CScript -E:VBS - の終焉報告です。
>Windows XP SP2で、スクリプトを標準入力から読み込む - 指定が効かなくなりました。

で、早速、代替策。

---execute.vbs---
Execute WScript.StdIn.ReadAll()
-----------------

echo MsgBox "aaa" | cscript execute.vbs

つちや さん 2004年 10月 08日 21時 09分 33秒

面白そうということで、ファイル一覧ソートに私も参加。(そういう企画じゃなかったかな)
つかのぺさんのとこにあるVBScriptのクイックソートはかなり速いですが、今回はADOを使って。自分でわかりやすくて、応用がきくもので。

Const adInteger = 3
Const adVarChar = 200

Set FS = CreateObject("Scripting.FileSystemObject")

Set RS = CreateObject("ADODB.Recordset")
RS.Fields.Append "FDate",adInteger
RS.Fields.Append "FFile",adVarChar,256
RS.Open

Set Folder = FS.GetFolder("C:\WINDOWS\system32")
For Each File In Folder.Files
RS.Addnew
RS.Fields("FDate").Value = CDbl(File.DateLastModified)
RS.Fields("FFile").Value = File
RS.Update
Next

RS.Sort = "FDate DESC"

RS.MoveFirst
While Not RS.EOF
WScript.Echo RS.Fields("FFile").Value
RS.MoveNext
Wend

RS.Close
Set RS = Nothing

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

>いりや さん 2004年 10月 06日 12時 34分 12秒
>ソート関数の引数に要素を比較する関数オブジェクトを与えて実現
>できるとおもいます。以下サンプルです。

C:\windows\system32で昇順で試しますと15.8秒でした。

やはり、性能上の所謂ホットスポットである比較関数で、処理の重い、
オブジェクト参照するのが、構造的によくないのではないかと思います。
>var discriminator1 = function discriminator1 (a, b) { return a.dateLastModified - b.dateLastModified };

>管理人むたぐち さん (mutaguchi@roy.hi-ho.ne.jp) 1999年 12月 22日 18時 02分 22秒
>To: 松田 出 さん
>>Filesコレクションはファイル名順に並ぶというデフォルト的な性質があるのでしょうか。
>どうも、そうらしいですね。日付順のソートは、自分でしなければいけないようです。
>Dim strFile()
>Set Fs = WScript.CreateObject("Scripting.FileSystemObject")
>Set objFiles=Fs.GetFolder("C:\windows").Files
>ReDim strFile(objFiles.Count-1,1)
>For Each objFile In objFiles
>strFile(I,0)=objFile.Path
>strFile(I,1)=objFile.DateLastModified
>For J=0 To I
>If strFile(I,1) < strFile(J,1) Then '不等号の向きで、昇順・降順が変えられる
>tmp1=strFile(I,1)
>tmp2=strFile(I,0)
>strFile(I,1)=strFile(J,1)
>strFile(I,0)=strFile(J,0)
>strFile(J,1)=tmp1
>strFile(J,0)=tmp2
>End If
>Next
>I=I+1
>Next
>For I=0 To objFiles.Count-1
>str=str & strFile(I,0) & vbTab & strFile(I,1) & vbCrLf
>Next
>msgbox str
>しかし…。これはあきれるほど遅いなあ。たぶんアルゴリズムの問題でしょう。
>これはバブルソートってやつだと思うのですが、私は他のソート方法を
>知らないのです(^^;

と嘆くものでも、10.8秒でした。

むたぐち さんのを以下のように手直しすると、5.9秒になりました。

※たぶんアルゴリズムの問題ではなく、コーディングの問題だったのでしょう。

Dim strFile()
Set Fs = WScript.CreateObject("Scripting.FileSystemObject")
Set objFiles=Fs.GetFolder("C:\windows\system32").Files
ReDim strFile(objFiles.Count-1,1)
For Each objFile In objFiles
: tmp0=objFile.Path
: tmp1=objFile.DateLastModified
: For J=I-1 To 0 Step -1
: : If tmp1 >= strFile(J,1) Then
: : : Exit For
: : Else
: : : strFile(J+1,0)=strFile(J,0)
: : : strFile(J+1,1)=strFile(J,1)
: : End If
: Next
: strFile(J+1,0)=tmp0
: strFile(J+1,1)=tmp1
: I=I+1
Next
For I=0 To objFiles.Count-1
: WScript.Echo strFile(I,0) & vbTab & strFile(I,1)
Next

性能では、ヒープソートなどには負けますが、VBScript Onlyで、かつ、
コード量も少なくて、第一に、ソースが理解可能でいいかも。

※ヒープソートのソースは理解を放棄します。
どうせ、分かったところで役には立つまい...
これは負け惜しみなんかではなく、プラグマチストなだけです。

>ばんのしゃーによかばんた さん 2004年 10月 05日 22時 14分 08秒
>VBScriptのDate型をJSに渡すと、デフォルトのソート関数が、
>理解できないみたいで、ソートしてくれません。CDblして渡します。

だと、3.7秒。流石、餅は餅屋。

ばんのしゃーによかばんた さん 2004年 10月 08日 17時 04分 18秒

知らなかった、re.Replace(source,GetRef("置換関数"))。

>ばんのしゃーによかばんた さん 2004年 10月 03日 17時 31分 53秒
>If Not iFile.AtEndOfStream Then
>: line=iFile.ReadAll
>: Set re=New RegExp
>: re.IgnoreCase=True
>: re.Pattern="=\?UTF-8\?B\?.+?\?="
>: If re.Test(line) Then
>: : Do
>: : : Set matches=re.Execute(line)
>: : : For Each match In matches
>: : : : str=mime2sjis(Mid(match.Value,1+Len(START_ID),match.Length-Len(START_ID)-Len(Stop_ID)))
>: : : : line=Left(line,match.FirstIndex) & str & Mid(line,1+match.FirstIndex+match.Length)
>: : : Next
>: : Loop While matches.count>0
>: End If
>End If
>oFile.Write line
>Wscript.Quit
>Function mime2sjis(mime)

If Not iFile.AtEndOfStream Then
line=iFile.ReadAll
Set re=New RegExp
re.IgnoreCase=True
re.Pattern="=\?UTF-8\?B\?(.+?)\?="
re.Global=True
line=re.Replace(line,GetRef("mime2sjis"))
End If
oFile.Write line
Wscript.Quit

Function mime2sjis(match,mime,pos,source)

置換関数(match,[submatch1,submatch2...,]pos,source)

ばんのしゃーによかばんた さん 2004年 10月 08日 17時 03分 33秒

O-1型 オブジェクト参照を解放するとオブジェクトが終了する。
を確認するVBSのサンプル。

ルートのオブジェクト参照を解放するとチェイン先のオブジェクトが
次々に終了する様子が分かります。

Class LinkedList
Public nexto
Public value
Sub Class_Terminate()
WScript.Echo value,"ended"
End Sub
End Class

Function initialize()
Set z = new LinkedList
z.value="z"
Set z.nexto=Nothing
Set y = new LinkedList
y.value="y"
Set y.nexto=z
Set x = new LinkedList
x.value="x"
Set x.nexto=y
Set w = new LinkedList
w.value="w"
Set w.nexto=x
Set v = new LinkedList
v.value="v"
Set v.nexto=w
Set initialize=v
End Function

Set a=initialize()

Set a=Nothing
WScript.Echo "END"

ばんのしゃーによかばんた さん 2004年 10月 08日 17時 02分 52秒

>ばんのしゃーによかばんた さん 2004年 10月 04日 21時 01分 50秒
>>魔界の仮面弁士 さん 2004年 10月 01日 20時 37分 54秒
>>WScriptオブジェクトのGetObjectメソッド(GetObject関数に非ず)って、
>>URLの取得が出来たんですね。全く知りませんでした……。
>>Set Doc = WScript.GetObject(URL)
>同じく、知りませんでした。
>Set HTMLDocument = GetObject("hege.htm","htmlfile")
>は、出来ても、
>Set HTMLDocument = GetObject("about:blank","htmlfile")
>は、CScript/WScriptが死んでましたものね。

などと言ってましたが、

>ばんのしゃーによかばんた さん 2004年 04月 02日 18時 55分 39秒

によれば、

>Set Document=GetObject("about:blank","htmlfile")
>や
>Set Document=GetObject("res://mshtml.dll/blank.htm","htmlfile")
>は、IEのVersionに依存して、5.5 動く、5.0 動かないようです。
>動く場合には、どちらも「マイコンピュータ」ゾーンになるようです。

ということなので、

IE 5.0 動かない
IE 5.5 動く
IE 6.0 動かない
と仕様が揺れているようです。

WScript.GetObject(URL)は、IE5.5の名残り、修正漏れ、で、今後、駄目になるのかも。

更に、Windows XP SP2で、

ie.navigate res://mshtml.dll/blank.htm

が、マイコンピュータゾーンからインターネットゾーンに変わっています。
クリップボード操作などで、これを利用していると動かなくなります。

セキュリティホールでもあったのかな。もし、そうなら、
マイコンピュータゾーンのセキュリティレベルを上げてなかったひとは危険だったかも。

ばんのしゃーによかばんた さん 2004年 10月 07日 17時 07分 07秒

CScript -E:VBS - の終焉報告です。

Windows XP SP2で、スクリプトを標準入力から読み込む - 指定が効かなくなりました。

まぁ、実際上、ほとんど使えない機能だったのですが、縮小均衡はとっても残念です。
ちゃんと使えるようにして欲しかった。


ばんのしゃーによかばんた さん 2004年 10月 07日 17時 06分 06秒

O-3型 オブジェクト参照を解放しないとオブジェクトが終了しない。...Excel

Set xl = CreateObject("Excel.Application")
xl.Visible=True
xl.workbooks.add
Set xl=Nothing
WScript.Quit

オブジェクト参照を解放しても、Excelは終了しません。

---

Set xl = CreateObject("Excel.Application")
xl.Visible=True
xl.workbooks.add
MsgBox "!"
Set xl=Nothing
WScript.Quit

GUIでExcelを終了しても、プロセスは残っています。

CScriptで実行してCTRL-Cで強制終了すると、オブジェクト参照のカウンタが
デクレメントされないので、このExcelは永久に残ります。xl.Quitは効きません。

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

O-2型 オブジェクト参照を解放しなくてもオブジェクトが終了する。...IE

Set ie=CreateObject("InternetExplorer.Application")
ie.Visible=True
url="c:\vbs\ie\blank.htm"
ie.Navigate url
Do While ie.Busy Or ie.ReadyState<>4
: WScript.Sleep 100
Loop

Set window=ie.Document.parentWindow
Set window=window.open(url,"z")
Set window=window.open(url,"y")
Set window=window.open(url,"x")
Set window=window.open(url,"w")
Set window=window.open(url,"v")

'×案

Do While Not (window Is Nothing)
: WScript.Echo window.name,"closed"
: window.close
: If IsEmpty(window.opener) Then
: : Set window=Nothing
: Else
: : Set window=window.opener
: End If
Loop
WScript.Echo "END"

'△案

Do While Not (window Is Nothing)
: If IsEmpty(window.opener) Then
: : Set window2=Nothing
: Else
: : Set window2=window.opener
: End If
: WScript.Echo window.name,"closed"
: window.close
: Set window=window2
Loop
WScript.Echo "END"

'○案

Do While Not (window Is Nothing)
: Set window2=window
: If IsEmpty(window.opener) Then
: : Set window=Nothing
: Else
: : Set window=window.opener
: End If
: WScript.Echo window2.name,"closed"
: window2.close
Loop
WScript.Echo "END"


ばんのしゃーによかばんた さん 2004年 10月 07日 17時 04分 40秒

オブジェクト参照の解放とオブジェクトの終了の関係には、以下の3類型があります。
O-1型 オブジェクト参照を解放するとオブジェクトが終了する。
O-2型 オブジェクト参照を解放しなくてもオブジェクトが終了する。...IE
O-3型 オブジェクト参照を解放しないとオブジェクトが終了しない。...Excel

>いりや さん 2004年 09月 29日 02時 22分 49秒
>ふむ。ぱっと見てなぜ×なのか、わからなかったのですが、
>function LinkedList(value, next) {
>    this.next = next;
>    this.value = value;
>}
>var z = new LinkedList('z', null);
>var y = new LinkedList('y', z);
>var x = new LinkedList('x', y);
>var w = new LinkedList('w', x);
>var v = new LinkedList('v', w);
>for (var p = v; p; p = p.next)
>    WScript.echo(p.value);
>for (var p = v; p; p = p.next)
>    p = null; // the object bound to var p will be gc'ed.
>と JScript に書いてみてわかりました。

は、O-1型です。

function LinkedList(value, next) {
    this.next = next;
    this.value = value;
}

function initialize(){
var z = new LinkedList('z', null);
var y = new LinkedList('y', z);
var x = new LinkedList('x', y);
var w = new LinkedList('w', x);
var v = new LinkedList('v', w);
return(v);
}

var v=initialize();

の場合、単純に終了させるだけなら、

v=null;

だけで済みます。

終了処理、例えば終了メッセージ、を追加するなら、

△案
for (var p = v; p; p = p.next)
    WScript.echo(p.value + ' ended.');
v=null;

○案
for (; v; v = v.next)
    WScript.echo(v.value + ' ended.');

×案
該当なし。


うさぎ さん 2004年 10月 07日 10時 49分 40秒

管理人さま、うさぎです。
すみませんが10月6日の質問記事とこの投稿2件削除してください。
間違って、貼り付けました。よろしくお願いします。

ばんのしゃーによかばんた さん 2004年 10月 06日 19時 57分 33秒

>ばんのしゃーによかばんた さん 2004年 10月 03日 18時 28分 09秒
>蛇の道は蛇。OS屋さんの考えそうなことを想像すると、
>MALLOC_CHECK_をセットすると、まず、mallocした領域にゴミを埋める。これは、
>mallocでやるより、ぺージ割り当て時とfree時にやる。
>それから、割り当て単位が16バイトなら、要求が端数のとき、次のバイトにマークを書く。
>freeでは、変なアドレスをエラーにする。マークを確認して消されていたらエラーにする。
>次のmallocに備えてゴミを埋める。そんなところでしょうか。

補足すると、ゴミを埋めるのは、
mallocして初期化せずに使っている障害を顕在化させる。のと、
mallocしてない領域への書き込みを検出するため。
後者は適時パトロールして、検出。

>| Recent versions of Linux libc (later than 5.4.23) and GNU
>| libc (2.x) include a malloc implementation which is tun-
>| able via environment variables. When MALLOC_CHECK_ is
>| set, a special (less efficient) implementation is used

この文は、ここまではいいけど。この後はなんか変ですね。

>| which is designed to be tolerant against simple errors,
>| such as double calls of free() with the same argument, or
>| overruns of a single byte (off-by-one bugs).

simple errorsしても、そのプログラムは大丈夫走り続ける。
と言っているようですけど、それは、誤解で、真意は、
simple errorsをdetectして、そのプログラムはabortさせる。
だから、システム全体としては大丈夫と言っている。
のではありますまいか。原文が悪いのか、英文解釈が悪いのか、
分かりませんが。

だって、overruns of a single byteはメモリを余分に取れば可能ですが、
二重解放しても大丈夫なんてことは、有り得ません。
malloc(*1),free(*2),malloc(*3),free(*4)のfree(*4)がfree(*2)の
二重なのか、malloc(*3)のfreeなのか区別できないですから。

うさぎ さん 2004年 10月 06日 15時 10分 05秒

いりやさんはじめまして。全くの初心者で申し訳ないんですが、質問させていただきます。
 
まず流れとしては、
(1)IEアクティブ後、フォーム入力、貼り付け作業
(2)プルダウンリスト選択時の画面切り替え時(ページ読込み中)
  にwaitをかける。
(3)選択フォーム表示後、貼り付け作業を行い、また別のプルダウンを選択する。
一連の流れを作るためにはSleep()では安定せず、質問をさせていただきました。

いくつかのプルダウンフォームの間にwaitを割り込ませることは可能でしょうか?
表示完了後の待ち時間は0.5〜1秒位で移行させようと考えています。

ACW(GETID("+XYZ+ - IE","IEFrame"),0,0,0,0,0)
MOUSEORG(GETID("+XYZ+ - IE","IEFrame"))

BTN(LEFT,CLICK,100,100,100)//プルダウンフォーム選択

KBD(VK_DOWN,CLICK,0) //"A"プルダウン↓
KBD(VK_DOWN,CLICK,0) //"B"プルダウン↓
KBD(VK_DOWN,CLICK,0) //で"C"を選択
KBD(VK_RETURN,CLICK,10)//クリックで別のフォームを読み込み中...

//ここで"C"のフォームを表示するまでWAITさせたいのです。SLEEP()では安定しません。
//ステータスに[ページが表示されました]のメッセージ後、Cフォームにデータを貼り付ける。

IE_DefaultWaitTime = 300//●ここが判りません。
//●読み込み後、3秒WAITさせたつもりでしたが...だめでした。

下記はいりや様のHPから拝借したものですが、どうしてもわからないので質問させて下さい。

// UWSC Sample Script

MSGBOX("価格.com を訪れます。");
価格ドットコムを訪れる();
MSGBOX("読み込みが完了しました。");
//(1)
procedure 価格ドットコムを訪れる()
anInternetExplorer = CREATEOLEOBJ("InternetExplorer.Application");
anInternetExplorer.visible = boolInUWSC→boolInCOM(true);
aURL = "http://www.kakaku.com";
anInternetExplorer.navigate(aURL);
waitUntilLoadingHasCompleted(anInternetExplorer); // We ignore the return value.
fend
//(2)
function waitUntilLoadingHasCompleted(anInternetExplorer)
waitSecs = 0.1;
READYSTATE_COMPLETE = 4;
repeat
SLEEP(waitSecs);
b1 = boolInCOM→boolInUWSC(anInternetExplorer.busy) = false;
b2 = anInternetExplorer.readyState = READYSTATE_COMPLETE;
breakCondition = b1 and b2;
until breakCondition // repeat until breakCondition becomes true.
result = true;
fend
//(3)
function boolInCOM→boolInUWSC(expr)
result = false;
ifb expr = -1 then
result = true;
elseif expr = 0 then
result = false;
endif
fend
//(4)
function boolInUWSC→boolInCOM(expr)
result = false;
ifb expr = true then
result = -1;
elseif expr = false then
result = 0;
endif
fend

●質問

(2)の,READYSTATE_COMPLETE = 4;の意味
    b1,b2の定義について
(3)の,boolInCOM→boolInUWSC(expr)の意味
    expr=-1と0の判断内容について
(4)の,boolInUWSC→boolInCOM(expr)の意味
   質問ばかりですみません。
   (1)対して(2)の判定。(2)に対して(3)(4)の判定でしょうか?
 
どうかご指南のほど、よろしくお願いします。



いりや さん 2004年 10月 06日 12時 34分 12秒

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

| ばんのしゃーによかばんた さん 2004年 10月 05日 22時 14分 08秒
|
| VBScriptのDate型をJSに渡すと、デフォルトのソート関数が、
| 理解できないみたいで、ソートしてくれません。CDblして渡します。

ソート関数の引数に要素を比較する関数オブジェクトを与えて実現
できるとおもいます。以下サンプルです。

六つの比較関数 (オブジェクト) を Array.prototype.sort() に与
えて配列の全要素を印刷します。

WScript.stdout を使用していますので、cscript.exe で実行する
必要があります。またファイルにリダイレクトしてから確認した方
がよいでしょう。

// ここから

(function () {
    var $ = Array.prototype;
    $.do_ = function (operation) {
        for (var i = 0; i < this.length; i++)
            operation(this[i]);
    }
})();

(function () {
    var $ = Enumerator.prototype;
    $.asArray = function () {
        var anArray = new Array();
        for (; !this.atEnd(); this.moveNext())
            anArray.push(this.item());
        return anArray;
    }
})();

var FileSystemObject = new ActiveXObject('Scripting.FileSystemObject');
var fileArray = new Enumerator(FileSystemObject.getFolder('.').files).asArray();

var discriminator1 = function discriminator1 (a, b) { return a.dateLastModified - b.dateLastModified };
var discriminator2 = function discriminator2 (a, b) { return - discriminator1(a, b) };
var discriminator3 = function discriminator3 (a, b) { return a.dateCreated - b.dateCreated };
var discriminator4 = function discriminator4 (a, b) { return - discriminator3(a, b) };
var discriminator5 = function discriminator5 (a, b) { return a.dateLastAccessed - b.dateLastAccessed };
var discriminator6 = function discriminator6 (a, b) { return - discriminator5(a, b) };

var discriminatorArray = new Array(
    discriminator1,
    discriminator2,
    discriminator3,
    discriminator4,
    discriminator5,
    discriminator6
);

var printBlock = function (file) {
    writeStream.write(file.dateLastModified);
    writeStream.write('\t');
    writeStream.write(file.dateCreated);
    writeStream.write('\t');
    writeStream.write(file.dateLastAccessed);
    writeStream.write('\t');
    writeStream.write(file.name);
    writeStream.writeBlankLines(1);
};

var writeStream = WScript.stdout;

try {
    discriminatorArray.do_(function (discriminator) {
        writeStream.writeLine('//');
        writeStream.writeLine('// Discriminator: [' + discriminator.toString() + ']');
        writeStream.writeLine('//');
        writeStream.writeBlankLines(1);
        writeStream.write(' dateLastModified ');
        writeStream.write('\t');
        writeStream.write('  dateCreated  ');
        writeStream.write('\t');
        writeStream.write(' dateLastAccessed ');
        writeStream.write('\t');
        writeStream.write('name');
        writeStream.writeBlankLines(1);
        fileArray.sort(discriminator);
        fileArray.do_(printBlock);
        writeStream.writeBlankLines(1);
    });
} finally {
    writeStream.close();
}

// ここまで

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

>ばんのしゃーによかばんた さん 2004年 09月 09日 18時 13分 46秒
>最終更新日時順ソートのサンプル。

VBScriptのDate型をJSに渡すと、デフォルトのソート関数が、
理解できないみたいで、ソートしてくれません。CDblして渡します。

Set fso=CreateObject("Scripting.FileSystemObject")
Set dic=CreateObject("Scripting.Dictionary")
Set Folder=fso.GetFolder(".")
For Each File In Folder.Files
: DateLastModified=CDbl(File.DateLastModified)
: If Not dic.Exists(DateLastModified) Then
: : dic.Add DateLastModified,Array(File)
: Else
: : a=dic.Item(DateLastModified)
: : Redim Preserve a(UBound(a)+1)
: : Set a(UBound(a))=File
: : dic.Item(DateLastModified)=a
: End If
Next
Set SC = CreateObject("ScriptControl")
SC.Language = "JScript"
Call SC.AddObject("dic",dic)
Set js=SC.Eval("new VBArray(dic.Keys())")
For Each DateLastModified In js.toArray().sort()
: For Each File In dic.Item(DateLastModified)
: : WScript.Echo File,File.DateLastModified
: Next
Next
WScript.Quit


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

>いりや さん 2004年 10月 03日 20時 16分 23秒
>これは契約によるプログラミングに出てくる事前条件の満足に通じ
>るものがありますね。

これは、インタフェース境界でのパラメタチェックの話でしょうか。
ちゃんとやろうとすると、これがまた、なかなか大変ですよね。
なので入口チェックだけでなく、処理中チェックも欠かせません。

>私は Bertrand Meyer さんのオブジェクト指向入門を読んで表明
>(Assertion) などの必要なキーワードを知りました。
>表明そのものは Jon L. Bentley さんのプログラマのうちあけ話の
>アルゴリズムの検査や XP だっけか、単体検査の枠組みでも導入さ
>れていますね。

よくあるのは、C の assert() macroをソースに仕込んでおいて、
テスト時だけ有効にすることですが、それではいけません。
本番運用時こそ、正しく動いていることを担保しなくては。

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

>管理人むたぐち さん 2004年 10月 05日 11時 45分 56秒
>echo password|runas...のようにしてもダメみたいですね。

話が外れますが、
なんか、標準入出力を嫌うコマンドがあるんですよね。

ヘルプを見ようとしても、初めの部分が流れて見えない。
runas /? | more
runas /? > file
とやっても、駄目。嫌っているとしか思えない。

コンソ−ルの行数を25から50くらいに増やすと、やっと見えます。ふー。


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

>管理人むたぐち さん 2004年 10月 05日 13時 16分 04秒
>そういえばWindows XP sp2をインストールすると、
>HTAのアイコンがコンソールアプリのものに変わりますね。
>今までずっとデフォルトアイコンだったことを考えると、凄い進歩です。

ん? 変わってないぞ、と思ったら、変更してました。

コンソールアプリよりこっちのほうがお勧めです。

REGEDIT4
[HKEY_CLASSES_ROOT\htafile\DefaultIcon]
@="\"C:\\Program Files\\Internet Explorer\\iexplore.exe\",21"
[HKEY_CLASSES_ROOT\htafile\ShellEx\DropHandler]
@="{60254CA5-953B-11CF-8C96-00AA00B8708C}"

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

>管理人むたぐち さん 2004年 10月 05日 03時 54分 48秒
>この掲示板において、MSMVP受賞者を、自分のほかにさらに二人も輩出できた

Windows Scripting Host Laboratoryという名前に相応しいですね。>所長さん。

それにしても、Visual Developer -Scripting分野の国産化率は高いですね。
ニッチなんでしょうか。
ほかの分野だとさらにMV-MVPを選んだほうがよさそうなくらい。

たけ さん 2004年 10月 05日 18時 56分 33秒

はじめまして、たけといいます。
WMIにて質問させていただきます。
質問内容:
 1台のPCに有線・無線LANがあり、無線LANの方を
 有効化/無効化をVB6で実現させたいのです。

色々検索してみたのですがC#のサンプルはあったのですが、
.NETは持っていませんので参考になりませんでした。

すみませんが宜しくお願いします。


管理人むたぐち さん 2004年 10月 05日 13時 16分 04秒

そういえばWindows XP sp2をインストールすると、
HTAのアイコンがコンソールアプリのものに変わりますね。
今までずっとデフォルトアイコンだったことを考えると、凄い進歩です。

管理人むたぐち さん 2004年 10月 05日 12時 07分 47秒

前ページの未解決分を新しい順に返信していきます。


To: ヤーポンレン さん

>  ・シェル統合モードでインストールされているかどうかを確認する方法

Set Shell = CreateObject("Shell.Application")
がエラーになればインストールされていない、と見るのではいかがでしょうか?
かなりアバウトな判定になりますが。

もしくは、FileSystemObjectのGetFileVersionメソッドで、shell32.dllの
バージョンを調べるのが確実です。 4.71以上だとシェル統合です。

ちなみに、Windows XP sp2では6.00.2900.2180 でした。

ただし、GetFileVersionメソッドは、古いバージョンのFileSystemObjectでは
サポートされていないので、そこでエラーになってしまう可能性もあります。

>  ・Shellを使う以外にファイルの所有者や作成者など、「概要」タブに
>   表示される項目を取得できる方法

これはちょっと分かりません。


To: ちゃっぴ さん

> WshShellオブジェクトにRegReadメソッドがありますが、
> これで"\"が含まれたキーを指定するにはどうしたらよいでしょうか?

試してみたところたしかにエラーになりますね。
RegReadメソッドでは無理なんじゃないでしょうか。
WMIのStdRegProvクラスを使うといけると思います。

いりや さん 2004年 10月 05日 12時 05分 34秒

Global Object つづき vol.1

Global Object そのものは単なる辞書で JScript のオブジェクト
として表現されているので操作の対象足りえるというところがユニー
クなところでしょうか。

ちょっと WiLiKi に GlobalObject なるものをこさえてみました。
お試しください。例題も用意しています。

http://iriyak.adam.ne.jp/wiliki/uwsc.cgi?iriyak%3aJScript%3aLibrary%3aGlobalObject&l=jp

シングルトンオブジェクトを返すメソッドと key/value の追加変
更を行うメソッドのみ提供しています。

辞書としての基本サービス (key/value を引数にした存在検査や
key を引数に value を返す機能など) を GlobalObject が提供す
べきかどうかは検討中で取り除いています。また key/value の追
加変更に加えて削除もできますがそれを取り入れるかも検討中です。

管理人むたぐち さん 2004年 10月 05日 11時 45分 56秒

To: MOG さん

> ある任意のコマンド(aa.cmd(仮称))を実行するように記述する場合、
> コマンドを実行するユーザーを、現時点でWindows上でログオンしている
> ユーザーではなく、どんなときでも「LocalSystem」ユーザーで起動する
> ように記述する方法はありませんでしょうか。

cmd /c runas /user:computername\LocalSystem aa.cmd

のように、runasコマンドを使えば良いでしょう。
実行はWshShell.Runなどで。

ただし、パスワードを入力する必要があります。
echo password|runas...のようにしてもダメみたいですね。
何か方法はありますでしょうか。

管理人むたぐち さん 2004年 10月 05日 03時 57分 04秒

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

> ところで、同じく、WScript.付きのCreateObjectの話ですが、
> WScript.CreateObject("InternetExplorer.Application","IE_")
> は、JScript.NETやVB.NETでは、代わりにどのように書くのでしょうか。

319342 - How To Handle Events for the Office XP Spreadsheet Component on a Windows Form in Visual Basic .NET
http://support.microsoft.com/default.aspx?scid=kb;EN-US;319342

この辺りが参考になったりならなかったりしそうです。
# すみません、よくは読んでないです。

管理人むたぐち さん 2004年 10月 05日 03時 54分 48秒

ご無沙汰しております。

ばんのしゃーによかばんたさん、いりやさん、MSMVP受賞おめでとうございます!
この掲示板において、MSMVP受賞者を、自分のほかにさらに二人も輩出できた
ことは大変喜ばしいことです。
これもみなさまの、とりわけ今回受賞のお二人、および推薦者の
魔界の仮面弁士さんのお陰です。本当にありがとうございました。

管理人は最近あまり顔を見せなくて申し訳ないですが、
管理人らしく、そしてMSMVP受賞者らしく、今後も頑張っていこうと
思いますので、よろしくお願いします。

ばんのしゃーによかばんた さん 2004年 10月 04日 21時 04分 17秒

>いりや さん 2004年 10月 03日 19時 31分 01秒
>これは malloc(3c) と合わせて時間があったときに見てみます。C
>FAQ 7.14 で malloc(3c) で得られたメモリブロックへのアクセス
>が発生するまで確保が先延ばしされる実装についての質問があって
>興味のある話題です。

mallocはアドレスを返すので、アドレス空間上はその時点で割り当てる
以外にないです。一方、実メモリと仮想メモリの外部記憶媒体上のスペースは、
不要です。最初のアクセス時にページフォルトを起こして、そのときに実ページを
割り当てる。最初にページアウトするときに外部記憶媒体上のスペースを割り当てる。
というのが普通の実装です。
ですから、パーフォマンスモニタで見ていると、mallocしても、実メモリ使用量や
swapファイル使用量は増えず、メモリをさわると、実メモリ使用量が増え、
メモリを書き進むと、swapファイル使用量は始めは変わらず、途中から増え出す。
という現象になると思います。

ばんのしゃーによかばんた さん 2004年 10月 04日 21時 03分 10秒

>いりや さん 2004年 10月 02日 02時 14分 34秒
>ところで、これを書きながら、ふと、積読 (つんどく) 状態にあった C プログ
>ラミング FAQ (以下 C FAQ) を開いてみたら 7.20, 7.21 にドンピシャで書いて
>あった。例題もぴったり。あちゃーです。

ほんとだ。×案、△案が載ってますね。

でも、○案が載ってませんよ。そこが肝心要なのに。

△案がいいように書いてるようでは駄目です。きっぱり。

ばんのしゃーによかばんた さん 2004年 10月 04日 21時 02分 24秒

>いりや さん 2004年 10月 02日 03時 07分 36秒
>というのは、この this 擬似変数にバインドされている global object を使う
>とグローバルコンテクストの変更が可能になるからです。
>グローバルコンテクストの変更が可能になるというのは具体的にどういうことか
>というとある変数への代入は、グローバル変数への代入になる。ある変数に関数
>オブジェクトを代入すると、実行中、どのコンテクストからでもその変数名を関
>数名として呼び出しが可能となるわけです。

なんか、「グローバルコンテクストの変更」というのがちんぷんかんぷんでしたが、

>ばんのしゃーによかばんた さん 2004年 09月 27日 17時 11分 15秒
>for(var m in this){
>WScript.Echo(m);
>}
を実行すると、

>WSH
>WScript
に加えて、
m
と出るので、おっかしいな。何かの間違いだろう。と無視していたのでした。

そういうことだったのですね。
理解できない事象を無視するのは、よくないですね。反省。

VBScriptのほうは、やっぱり、
>あまり役に立たない情報ですが、
ですね。なんか、寂しい。

ばんのしゃーによかばんた さん 2004年 10月 04日 21時 01分 50秒

>魔界の仮面弁士 さん 2004年 10月 01日 20時 37分 54秒
>WScriptオブジェクトのGetObjectメソッド(GetObject関数に非ず)って、
>URLの取得が出来たんですね。全く知りませんでした……。
>Set Doc = WScript.GetObject(URL)

同じく、知りませんでした。

Set HTMLDocument = GetObject("hege.htm","htmlfile")
は、出来ても、

Set HTMLDocument = GetObject("about:blank","htmlfile")
は、CScript/WScriptが死んでましたものね。

WScript.GetObjectなんてものが、あったんですね。
わざわざ、WScript.を付ける理由が見当たりませんし。
特徴である、第三パラメタを使った例って、あるのでしょうか。

---

しかし、新発見の
>Set Doc = WScript.GetObject(URL)

Set HTMLDocument = GetObject("hege.htm","htmlfile")
は、情報バーの警告なしに、セキュリティゾーンのセキュリティレベルに従って、
スクリプトが実行されるので、あまり使わないほうがよいのではないかと思います。
特別よいこともなさそうだし。

---

ところで、同じく、WScript.付きのCreateObjectの話ですが、
WScript.CreateObject("InternetExplorer.Application","IE_")
は、JScript.NETやVB.NETでは、代わりにどのように書くのでしょうか。

MOG さん 2004年 10月 04日 16時 59分 22秒

VBScript上から、
ある任意のコマンド(aa.cmd(仮称))を実行するように記述する場合、
コマンドを実行するユーザーを、現時点でWindows上でログオンしている
ユーザーではなく、どんなときでも「LocalSystem」ユーザーで起動する
ように記述する方法はありませんでしょうか。
よろしくお願いいたします。

Return