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        
無料ブログはココログ

« 2007年10月 | トップページ | 2007年12月 »

2007年11月30日 (金)

VB.NETで、RunningObjectTable(ROT)の表示名を列挙する、コマンドを作る。

GUIでは、IROTVIEW.exeなんてのがありますが。。。

Option Explicit
Imports System.Runtime.InteropServices.ComTypes
Public Class ROT
Private Declare Function CreateBindCtx Lib "ole32" (ByVal dwReserved As Integer, ByRef pBindCtx As IBindCtx) As Integer
Public Shared Sub Main()
Dim pbc As IBindCtx
CreateBindCtx(0, pbc)
Dim pprot As IRunningObjectTable
pbc.GetRunningObjectTable(pprot)
Dim ppenumMoniker As IEnumMoniker
pprot.EnumRunning(ppenumMoniker)
Dim rgelt(0) As IMoniker
Dim pceltFetched As Integer
Do While ppenumMoniker.Next(rgelt.Length, rgelt, pceltFetched) = 0
  Dim ppszDisplayName As String
  rgelt(0).GetDisplayName(pbc, Nothing, ppszDisplayName)
  Console.WriteLine(ppszDisplayName)
Loop
End Sub
End Class

2007年11月27日 (火)

Excel VBAからDDE経由、Adobe ReaderでPDFファイルを印刷する。

普通のやり方は、Shell()でアプリを起動して、DDEの[AppExit]で終了させます。
しかし、これだと多重処理で誤爆の可能性があります。
なので、オブジェクト生成でアプリを起動して、参照の解放で終了させます。
これなら、誤爆の心配がありません。

Sub PdfPrint(ParamArray Files() As Variant)
Dim fso As Object
Dim PDF As Object
Dim File As Variant
Dim ChannelNumber As Long

Set fso = CreateObject("Scripting.FileSystemObject")
Set PDF = CreateObject("AcroExch.Document")
ChannelNumber = Application.DDEInitiate("Acroview", "Control")
For Each File In Files
  File = fso.GetFile(File).Path
  Application.DDEExecute ChannelNumber, "[FilePrintSilent(""" & File & """)]"
Next
Application.DDETerminate ChannelNumber
End Sub

2007年11月26日 (月)

スクリプトからExcel DDEとAdobe ReaderでPDFファイルを印刷する。

もしExcelがあれば、DDEが使えるので、比較的、問題なく、PDFファイルが印刷できます。

PdfPrint.VBS PDFファイル...

Set fso=CreateObject("Scripting.FileSystemObject")
Set Application=CreateObject("Excel.Application")
Set PDF=CreateObject("AcroExch.Document")
ChannelNumber=Application.DDEInitiate("Acroview","Control")
For Each File In WScript.Arguments
  File=fso.GetFile(File).Path
  Application.DDEExecute ChannelNumber,"[FilePrintSilent("""&File&""")]"
Next
Application.DDETerminate ChannelNumber

2007年11月25日 (日)

スクリプトからExcel VBAステートメントを実行する。

スクリプトからExcelのSendKeysステートメントを使って「メモ帳」に"日本語"を送ります。

Set Application=CreateObject("Excel.Application")
Set Book=Application.Workbooks.Add
Set Module=Book.VBProject.VBComponents.Add(1)
Code="Sub xSendKeys(Text):SendKeys Text,True:End Sub"
Module.CodeModule.AddFromString Code
CreateObject("WScript.Shell").AppActivate "メモ帳"
WScript.Sleep 1000
Application.Run "xSendKeys","日本語"
Set Module=Nothing
Book.Saved=True
Application.Quit

Excelのオプションで、
[Visual Basic プロジェクトへのアクセスを信頼する]
がチェックされてる必要があります。

2007年11月24日 (土)

VBAのSendKeysは日本語を通す?

VBAのSendKeysは日本語を通さないと思っていたら、違うようです。
Application.SendKeys()メソッドやSEND.KEYS()マクロは日本語を通しませんが、VBAのSendKeysステートメントは日本語を通すようです。

なので、スクリプトからExcelを使って日本語をSendKeysできますね。

2007年11月23日 (金)

Excelファイルを含むフォルダをカレントディレクトリにして開く。

普通にExcelファイルを開くと、カレントディレクトリは固定の既定値になります。
これが面倒の元。省略値をそのExcelファイルを含むフォルダにしてくれ!つーの。

なので、関連付けを追加または変更しましょう。

方法1

commnandキー
"~\excel.exe" /p "%1\.." "%1"

ddeexecキーなし

方法2

ddeexecキー
[open("%1")][OPTIONS.GENERAL(,,,,,,,,,"%1\..")]

オプションの[既定のファイルの場所]を、そのExcelファイルを含むフォルダにします。

方法3

バッチファイルを作ってドロップする方法もあります。

excel.cmd Excelファイル

start excel.exe /p "%~dp1" "%~f1"

方法4

オプションの[既定のファイルの場所]を空にすると、起動時のカレントディレクトリになります。
エクスプローラから関連付けで起動すると、そのExcelファイルを含むフォルダになります。

2007年11月22日 (木)

バッチファイルやスクリプトからシフトキー類の押し下げ状態を調べる。(その2)

IEより、htmlfile のほうが性能的に軽い。

@if(0)==(0) ECHO OFF
CScript.exe //NoLogo //E:JScript "%~f0"
GOTO :EOF
@end
var ShiftKeys=new Array();
var Document=new ActiveXObject("htmlfile");
Document.write("<body></body>");
Document.close();
Document.body.onunload=OnUnload;
Document.write("<body></body>");
Document.close();
WScript.Echo(ShiftKeys.join(" + "));

function OnUnload(){
if(this.event.shiftLeft) ShiftKeys.push("shiftLeft");
if(this.event.shiftKey) ShiftKeys.push("shiftKey");
if(this.event.altLeft) ShiftKeys.push("altLeft");
if(this.event.altKey) ShiftKeys.push("altKey");
if(this.event.ctrlLeft) ShiftKeys.push("ctrlLeft");
if(this.event.ctrlKey) ShiftKeys.push("ctrlKey");
}

2007年11月21日 (水)

VB.NETでZIP圧縮コマンドを作る。

VBAからVB.NETに焼き直し。

MakeZIP.exe ZIPファイル ファイル...

vbc MakeZIP.VB

Option Explicit
Imports Microsoft.VisualBasic
Imports System
Imports System.IO
Imports System.Windows.Forms

Public Class Zip
Public Shared Function Main(ByVal Arguments() As String) As Integer
If Arguments.Length<2 Then
  Console.Error.WriteLine("Arguments Missing.")
  Console.Error.WriteLine("Usage: MakeZip zipfile files...")
  Return 1
End If
If Path.GetExtension(Arguments(0).ToLower()) <> ".zip" Then
  Console.Error.WriteLine("Invalid Extension Name - " & Arguments(0))
  Return 1
End If
If Not File.Exists(Arguments(0)) Then
  Dim fs As FileStream = File.Create(Arguments(0))
  Dim b As Byte() = {&H50, &H4B, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  fs.Write(b,0,b.Length)
  fs.Close()
End If
Dim Shell As Object = CreateObject("Shell.Application")
Dim zFolder As Object = Shell.NameSpace(Path.GetFullPath(Arguments(0)))
Dim k As Integer
For k = 1 To Arguments.Length-1
  Dim FileName As String = Path.GetFileName(Arguments(k))
  Dim sFolderItem As Object = Shell.NameSpace(Path.GetFullPath(Arguments(k) & "\..")).ParseName(FileName)
  If sFolderItem Is Nothing Then
    Console.Error.WriteLine("File Not Found. - " & Arguments(k))
    Return 1
  End If
  Do
    Dim zFolderItem As Object = zFolder.ParseName(FileName)
    If zFolderItem Is Nothing Then
      Dim Count As Integer = zFolder.Items().Count
      zFolder.CopyHere(sFolderItem)
      Do While zFolder.Items().Count =< Count
        Threading.Thread.Sleep(1000)
      Loop
      Exit Do
    Else
      Dim Ans As Integer = MessageBox.Show("このフォルダには既に次のファイルが存在します:" & ControlChars.Lf & ControlChars.Lf & _
        """" & FileName & """" & ControlChars.Lf & ControlChars.Lf & "既存のファイルと置き換えますか?", "ファイル置換の確認", _
        MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)
      Select Case Ans
      Case DialogResult.Yes
        zFolderItem.InvokeVerb("delete")
      Case DialogResult.No
        Exit Do
      Case DialogResult.Cancel
        Exit For
      End Select
    End If
  Loop
Next
End Function
End Class

ZIP圧縮のFolder.CopyHere()は非同期なので、Folder.Items().Countの変化を捕らえて、待ち合わせます。
置換では、変化しないので、削除して、追加します。

2007年11月20日 (火)

VBAでZIP圧縮する。

VBScriptからVBAに焼き直し。

Option Explicit

Sub MakeZIP(ZIPfile As String, ParamArray Files() As Variant)
Dim fso As Object
Dim Shell As Object
Dim zFolder As Object
Dim Path As Variant
Dim FileName As String
Dim sFolderItem As Object
Dim zFolderItem As Object
Dim Count As Long
Dim Ans As Long

Set fso = CreateObject("Scripting.FileSystemObject")
If UCase(fso.GetExtensionName(ZIPfile)) <> "ZIP" Then
  MsgBox "Invalid Extension Name - " & ZIPfile, vbCritical
  Exit Sub
End If
If Not fso.FileExists(ZIPfile) Then
  fso.CreateTextFile(ZIPfile, False).Write "PK" & Chr(5) & Chr(6) & String(18, 0)
End If
Set Shell = CreateObject("Shell.Application")
Set zFolder = Shell.Namespace(fso.GetAbsolutePathName(ZIPfile))
For Each Path In Files
  FileName = fso.GetFileName(Path)
  Set sFolderItem = Shell.NameSpace(fso.GetParentFolderName(fso.GetAbsolutePathName(Path))).ParseName(FileName)
  If sFolderItem Is Nothing Then
    MsgBox Path & " - Not Found.", vbCritical
    Exit For
  End If
  Do
    Set zFolderItem = zFolder.ParseName(FileName)
    If zFolderItem Is Nothing Then
      Count = zFolder.Items().Count
      zFolder.CopyHere sFolderItem
      Do While zFolder.Items().Count =< Count
        Application.Wait Now + TimeSerial(0, 0, 1)
      Loop
      Exit Do
    Else
      Ans = MsgBox("このフォルダには既に次のファイルが存在します:" & vbLf & vbLf & _
                 """" & FileName & """" & vbLf & vbLf & "既存のファイルと置き換えますか?", _
                 vbYesNoCancel + vbQuestion, "ファイル置換の確認")
      Select Case Ans
      Case vbYes
        zFolderItem.InvokeVerb ("delete")
      Case vbNo
        Exit Do
      Case vbCancel
        Exit For
      End Select
    End If
  Loop
Next
End Sub

2007年11月19日 (月)

VB.NETからAdobe ReaderでPDFファイルを印刷する。(その2)

.NETなら、こんなに簡単です。

Adobe Reader 6.0 ~ 8.1

印刷後、アプリが自動的に終了しないので、終了させます。

PdfPrint.VB

Imports System
Imports System.Diagnostics
Public Class PdfPrint
Public Shared Function Main(ByVal Arguments() As String) As Integer
Dim File As String
For Each File In Arguments
  Dim Process2 As Process=Process.Start("acrord32.exe","/n /p /h """ & File & """")
  Process2.WaitForInputIdle()
  Do
    Process2.CloseMainWindow()
  Loop Until Process2.WaitForExit(1000)
Next
End Function
End Class

お好みで、コンソールコマンドかウィンドウアプリにします。
vbc PdfPrint.VB
または、
vbc /t:winexe PdfPrint.VB

PdfPrint.exe PDFファイル...

2007年11月18日 (日)

VB.NETからAdobe ReaderでPDFファイルを印刷する。

.NETなら、こんなに簡単です。

Adobe Reader 7.0 ~ 8.1

最初にダミーのアプリを起こして、最後に終了させます。

PdfPrint.VB

Imports System
Imports System.Diagnostics
Public Class PdfPrint
Public Shared Function Main(ByVal Arguments() As String) As Integer
Dim Process1 As Process=Process.Start("acrord32.exe","/n /h")
Process1.WaitForInputIdle()
Dim File As String
For Each File In Arguments
  Dim Process2 As Process=Process.Start("acrord32.exe","/n /t """ & File & """")
  Process2.WaitForExit()
Next
Process1.CloseMainWindow()
End Function
End Class

お好みで、コンソールコマンドかウィンドウアプリにします。
vbc PdfPrint.VB
または、
vbc /t:winexe PdfPrint.VB

PdfPrint.exe PDFファイル...

2007年11月17日 (土)

VBAからAdobe ReaderでPDFファイルを印刷する。(その3)

Adobe Reader 7.0 ~ 8.1

Sub PdfPrint(ParamArray Files())
Dim wShell As Object
Dim Path As String
Dim pExec As Object
Dim k As Integer
Dim oExec As Object

Set wShell = CreateObject("WScript.Shell")
Path = wShell.RegRead("HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\acrord32.exe\")
Path = Replace(Path, """", "")
Path = wShell.ExpandEnvironmentStrings(Path)
Set pExec = wShell.Exec("""" & Path & """ /n /h""")
Do While Not wShell.AppActivate(pExec.ProcessID)
  Application.Wait Now + TimeSerial(0, 0, 1)
Loop
For k = 0 To UBound(Files)
  Set oExec = wShell.Exec("""" & Path & """ /n /t """ & Files(k) & """")
  Do While oExec.Status = 0
    Application.Wait Now + TimeSerial(0, 0, 1)
  Loop
Next
If pExec.Status = 0 Then pExec.Terminate
End Sub

SendKeys()を使わないので、SendKeys()が嫌いな人向き。:-p
その代わり、ダミーのアプリを起こすので、その分、ちと重くなりますが。。。

2007年11月16日 (金)

ZIP圧縮の待ち合わせ方法

また別の待ち合わせ方法です。ZIPファイルの更新日時の変化を捕らえます。

@if(0)==(0) ECHO OFF
CScript.exe //NoLogo //E:JScript "%~f0" %*
GOTO :EOF
@end
var Usage="Usage: MakeZIP.CMD ZIPfile files...";
if(WScript.Arguments.Count()<2){
  WScript.Echo(Usage);
  WScript.Quit();
}
var ZIPfile=WScript.Arguments.Item(0);
var fso=new ActiveXObject("Scripting.FileSystemObject");
if(fso.GetExtensionName(ZIPfile).toUpperCase()!="ZIP"){
  WScript.Echo("Invalid Extension Name -",ZIPfile);
  WScript.Quit();
}
if(!fso.FileExists(ZIPfile)){
  var File=fso.CreateTextFile(ZIPfile,false);
  File.Write("PK" + String.fromCharCode(5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0));
  File.Close();
}
var wShell=new ActiveXObject("WScript.Shell");
var vbYesNoCancel=3;
var vbQuestion=32;
var vbYes=6;
var vbNo=7;
var vbCancel=2;
var Shell=new ActiveXObject("Shell.Application");
var File=fso.GetFile(ZIPfile);
var zFolder=Shell.NameSpace(File.Path);
F1:for(var k=1;k<WScript.Arguments.Count();k++){
  var Path=WScript.Arguments.Item(k);
  var FileName=fso.GetFileName(Path);
  var sFolderItem=Shell.NameSpace(fso.GetParentFolderName(fso.GetAbsolutePathName(Path))).ParseName(FileName);
  if(!sFolderItem){
    WScript.Echo(Path,"- Not Found.");
    break;
  }
  W1:while(true){
    var zFolderItem=zFolder.ParseName(FileName);
    if(!zFolderItem){
      var ModifyDate=new Date(File.DateLastModified);
      zFolder.CopyHere(sFolderItem);
      while(ModifyDate.valueOf()==new Date(File.DateLastModified).valueOf()) WScript.Sleep(100);
      break;
    }else{
      var Ans=wShell.PopUp("このフォルダには既に次のファイルが存在します:\n\n"+
                 '"' + FileName + '"\n\n既存のファイルと置き換えますか?',
                 0,"ファイル置換の確認",vbYesNoCancel+vbQuestion);
      switch(Ans){
      case vbYes:
        zFolderItem.InvokeVerb("delete");
        break;
      case vbNo:
        break W1;
      case vbCancel:
        break F1;
      }
    }
  }
}
WScript.Quit();

2007年11月12日 (月)

Command.com用バッチファイルをJSファイルにラップする。

Command.com用のバッチファイルをJSファイルにラッピングします。なんのこっちゃ?

拡張子.bat2jsを作成し、ファイルクラスjsfileに関連付けます。

この拡張子は、長いファイル名では、JSファイルとなり、短いファイル名では、Command.com用のバッチファイルになります。

バッチとして実行するときは、
Command.com /C 短いファイル名
で、実行します。

引数のないバッチファイル.bat2js

@if(0==0)WScript.Quit(new ActiveXObject('WScript.Shell').Run('command.com /c ' + new ActiveXObject('Scripting.FileSystemObject').GetFile(WScript.ScriptFullName).ShortPath,7,true));@else
echo %%0=%0
pause
:@end

引数のあるバッチファイル.bat2js

@if(0)==(0) ECHO OFF
echo %%0=%0
echo %%1=%1
pause
EXIT
@end
var args=new Array();args.push('command.com');args.push('/c');
args.push(new ActiveXObject('Scripting.FileSystemObject').GetFile(WScript.ScriptFullName).ShortPath);
for(var k=0;k<WScript.Arguments.Count();k++){
var arg=WScript.Arguments.Item(k);args.push(arg.indexOf(' ')+1?'"'+arg+'"':arg);}
new ActiveXObject('WScript.Shell').Run(args.join(' '),7);

ここでは、最小化ですが、コンソール入出力が必要なければ、非表示にも出来ます。

CMD.EXEは、短いファイル名を指定しても、長いファイル名に翻訳するため、使えません。

2007年11月11日 (日)

関連付けは非同期実行なので、連続処理に向かない。

ShellExecuteやInvokeVerbなどによる関連付け動詞の実行は、非同期です。

なので、連続実行すると、マルチインスタンスの場合、プロセスが大量に生成されてスローダウンしたり、
シングルインスタンスの場合、順序が逆転したり、多重処理に対応できず、処理要求抜けが生じたりします。

連続処理するときは、そろぞれのアプリごとに1ファイルの同期処理を作り、それを繰り返し呼び出すようにします。

2007年11月10日 (土)

VBAからAdobe ReaderでPDFファイルを印刷する。(追記)

VBAからAdobe Readerで印刷する。(その2)
などで、解決済みなのですが、未だに頓珍漢な情報が流されてるようで困ったものです。:-(

この例で、特に支障なく動作するのですが、それを実際に試しもせずに、SendKeysを使ってるから駄目とか、教条主義的に決め付けるのはやめましょう。
また、代わりに、思い付きで、まともに動かない例を提示するのもやめましょう。
ちゃんと動作検証して、問題を十分理解してからにしてください。つーの。全く。。。

例えば、ShellExecuteやInvokeVerbでPrint Verbをキックする。

→ アプリが終了しないで残る。
→ 初回複数連続印刷で抜けが生じる。

⇒ これは、ダミーのインスタンスを起こして、後始末すれば大丈夫なんだけど。。。

例えば、FindWindow+WM_CLOSEやSC_CLOSEをSendMessageする。

→ 別のインスタンスを誤爆。

⇒ これは、プロセスIDで識別すれば大丈夫なんだけど。。。

例えば、COMオブジェクトを使え。

→ アプリ終了手段が用意されてないので、アプリが終了しないで残る。
→ 印刷しようとすると、警告ダイアログが出る。次から出さないようにはできるが、ユーザ依存だし、自動化できない。

例えば、DDEを使え。

→ 多重に使うと、別のインスタンスを誤爆するリスクが若干あるものの、シングルで使う分には確実なのでお勧め。

2007年11月 8日 (木)

一時ファイルにスクリプトを書いて子プロセスを起こす。(その3)

ProcessIDが必要なときは、Exec()を使います。

標準入出力を使うときも、Exec()を使います。

Set fso=CreateObject("Scripting.FileSystemObject")
Path=fso.BuildPath(fso.GetSpecialFolder(2).Path,fso.GetTempName())
Set File=fso.CreateTextFile(Path)
File.WriteLine "Set fso=CreateObject(""Scripting.FileSystemObject"")"
File.WriteLine "fso.DeleteFile WScript.ScriptFullName"
File.WriteLine "MsgBox fso.GetStandardStream(0).AtEndOfStream,,WScript.ScriptFullName"
File.Close
Set wShell=CreateObject("WScript.Shell")
Set oExec=wShell.Exec("wscript.exe //e:vbs """ & Path & """")
MsgBox oExec.ProcessID,,"ProcessID"

fso.GetStandardStream()を使えば、CScript.exeを使う必要はありません。

一時ファイルにスクリプトを書いて子プロセスを起こす。(その2)

一時ファイルを子側で削除する例です。

Set fso=CreateObject("Scripting.FileSystemObject")
Path=fso.BuildPath(fso.GetSpecialFolder(2).Path,fso.GetTempName())
Set File=fso.CreateTextFile(Path)
File.WriteLine "CreateObject(""Scripting.FileSystemObject"").DeleteFile WScript.ScriptFullName"
File.WriteLine "MsgBox WScript.ScriptFullName"
File.Close
Set wShell=CreateObject("WScript.Shell")
wShell.Run "wscript.exe //e:vbs """ & Path & """"

一時ファイルを子側で削除する場合は、非同期で実行できます。
削除もれがないよう、スクリプトの最初に削除します。削除しても、スクリプトの実行には関係ありません。

一時ファイルにスクリプトを書いて子プロセスを起こす。

ひとつのスクリプトファイルから親子プロセスに分けて実行するには、
WSF、再帰呼び出し、MSHTAを使う方法などがありますが、
これは、一時ファイルのスクリプトファイルを作るパラダイムです。

一時ファイルを親側で削除する例です。

Set fso=CreateObject("Scripting.FileSystemObject")
Path=fso.BuildPath(fso.GetSpecialFolder(2).Path,fso.GetTempName())
Set File=fso.CreateTextFile(Path)
File.WriteLine "MsgBox WScript.ScriptFullName"
File.Close
Set wShell=CreateObject("WScript.Shell")
wShell.Run "wscript.exe //e:vbs """ & Path & """",,True
fso.DeleteFile Path

一時ファイルを親側で削除するには、同期が必要です。
子側がファイルを読み込むまででよいのですが、分からないので終了まで。

2007年11月 6日 (火)

バッチファイルからインラインのVBScriptスクリプト

初期のWScript.exe/CScript.exeでは、スクリプトファイルを作らなくても、
- を指定すると、標準入力からスクリプトを読み込んで実行できました。
これを使ってバッチファイルからインラインスクリプトが実行できました。
後のWScript.exe/CScript.exeでは、これができなくなりました。
そこで、代わりに一時ファイルのスクリプトファイルを作るパラダイムです。

一時ファイルをバッチファイル側で削除する例
SetLocal
Set File=%TEMP%\tmp%RANDOM%.vbs
Echo MsgBox "%File%" >"%File%"
WScript.exe "%File%"
Del "%File%"

一時ファイルをスクリプト側で削除する例
SetLocal
Set File=%TEMP%\tmp%RANDOM%.vbs
Echo CreateObject("Scripting.FileSystemObject").DeleteFile WScript.ScriptFullName >"%File%"
Echo MsgBox "%File%" >>"%File%"
WScript.exe "%File%"

1行スクリプトの例
CMD /V:ON /S /C "Set File=!TEMP!\tmp!RANDOM!.vbs & Echo MsgBox "!File!" >"!File!" & WScript.exe "!File!" & Del "!File!""

2007年11月 3日 (土)

ショートカットの「実行時の大きさ」を「非表示」にする。(その2)

パイプを使わないで、リダイレクションでやると、

非表示に変更.CMD ショートカット.lnk

@goto :end
e 13c 0
w
q
:end
debug %1 <%0

ところが、16ビットアプリのリダイレクションは、ファイルをオープンしっぱなしにするようです。(障害?)

これも、command.com のリダイレクションを使えば大丈夫なようです。

@goto :end
e 13c 0
w
q
:end
command /c debug %1 ^<%0

ショートカットの「実行時の大きさ」を「非表示」にする。

バッチファイルで、ショートカットの「実行時の大きさ」を「非表示」に変更します。

非表示に変更.CMD ショートカット.lnk

@echo off
(
echo e 13c 0
echo w
echo q
)|debug %1

ところが、32ビットアプリと16ビットアプリの間のパイプラインは、
C:\Windows\Temp

scsXXXX.tmp
というパイプ代替の一時ファイルのゴミが残ります。(障害?)

command.com のパイプを使えば大丈夫なようです。

@command /c cmd /s /c"echo e 13c 0&echo w&echo q"^|debug %1

2007年11月 2日 (金)

Excel VBAでミリ秒の時間を待つ。

100ミリ秒待つのに、Excelマクロを使えば、

Application.Wait [NOW()+"0:00:00.1"]

VBAだけで、

秒の誤差があってよければ、
Application.Wait CDbl(Now) + (Timer - Fix(Timer)) / 24 / 60 / 60 + CDbl(1) / 24 / 60 / 60 / 10

更に、秒の誤差がでないようにするには、

Do
  dt = Now
  tm = Timer
Loop While dt <> Now
Application.Wait CDbl(dt) + (tm - Fix(tm)) / 24 / 60 / 60 + CDbl(1) / 24 / 60 / 60 / 10

リトライは、例えば、Now=1秒9とTimer=2秒1が合成されて、1秒1となるのを防ぎます。

以下は要注意です。

Application.Wait(Date型) では、ミリ秒が秒に丸められます。

Application.Wait(Double型) では、ミリ秒が有効になります。

Excel VBAで時刻のミリ秒を得る。

簡単なのはExcelマクロを使うことですが、

[NOW()]

[NOW()]はDouble型で、最小単位はミリ秒。精度は10ミリ秒。

Excelマクロを使わない方法もあります。

Do
  dt = Now
  tm = Timer
Loop While dt <> Now
dt = dt + (tm - Fix(tm)) / 24 / 60 / 60

Now()、Time()はDate型で、精度は秒。
Timer()はSingle型で、精度は0.0078125(1/128)秒。

リトライは、例えば、Now=1秒9とTimer=2秒1が合成されて、1秒1となるのを防ぎます。

2007年11月 1日 (木)

スクリプトで、テキストファイルの先頭行を削除する。

原理は同じです。あまり難しいことは考えないほうがよいでしょう。

Path=WScript.Arguments.Item(0)
Set fso=CreateObject("Scripting.FileSystemObject")
Set File=fso.OpenTextFile(Path)
File.SkipLine
Text=File.ReadAll
File.Close
Set File=fso.OpenTextFile(Path,2)
File.Write Text
File.Close

« 2007年10月 | トップページ | 2007年12月 »