SQLの窓

2019年03月07日


VBScript : 複数テキストファイルの charset(キャラクタセット) 一括変換 / ADODB.Stream

ADODB.Stream を使用すると、テキストファイルのキャラクタセットををメモリ内で変換する事ができます

※ 変換元と変換後のキャラクタセットを指定する必要があります
※ ここでの対象ディレクトリはカレントにある "res" ディレクトリです
※ SaveToFile オプションの 2 は 上書きを意味します

utf8(BOMあり) または utf8n より shift_jis
'****************************************
' utf8(BOMあり) または utf8n より shift_jis
'****************************************

Set Fso = CreateObject( "Scripting.FileSystemObject" )
Set Stream1 = CreateObject("ADODB.Stream")
Set Stream2 = CreateObject("ADODB.Stream")

Set objFolder = Fso.GetFolder( "res" )
Set objFiles = objFolder.Files

For each objFile in objFiles
	' フルパス
	strFullPath = Fso.GetAbsolutePathName( "res\" & objFile.Name )

	' utf-8 として開く( utf8 でも utf8n でも OK )
	Stream1.Open
	Stream1.Type = 2	' StreamTypeEnum の adTypeText(デフォルト)
	Stream1.Charset = "utf-8"

	' utf-8 として読み込む
	Stream1.LoadFromFile strFullPath

	' shift_jis として開く
	Stream2.Open
	Stream2.Type = 2
	Stream2.Charset = "shift_jis"

	' utf-8 から shift_jis に変換コピーする
	Stream1.CopyTo Stream2
	Stream2.SaveToFile strFullPath, 2	' 上書き保存

	' ストリームを閉じる
	Stream2.Close
	Stream1.Close

Next

MsgBox("処理が終了しました")


shift_jis から utf8( BOMあり )
'****************************************
' shift_jis から utf8( BOMあり )
'****************************************
Set Fso = CreateObject( "Scripting.FileSystemObject" )
Set Stream1 = CreateObject("ADODB.Stream")
Set Stream2 = CreateObject("ADODB.Stream")

Set objFolder = Fso.GetFolder( "res" )
Set objFiles = objFolder.Files

For each objFile in objFiles
	' フルパス
	strFullPath = Fso.GetAbsolutePathName( "res\" & objFile.Name )

	' shift_jis として開く
	Stream1.Open
	Stream1.Type = 2	' StreamTypeEnum の adTypeText(デフォルト)
	Stream1.Charset = "shift_jis"

	' shift_jis として読み込む
	Stream1.LoadFromFile strFullPath

	' utf-8 として開く
	Stream2.Open
	Stream2.Type = 2
	Stream2.Charset = "utf-8"

	' shift_jis から utf-8 に変換コピーする
	Stream1.CopyTo Stream2
	Stream2.SaveToFile strFullPath, 2	' 上書き保存

	' ストリームを閉じる
	Stream2.Close
	Stream1.Close

Next

MsgBox("処理が終了しました")


shift_jis から utf8n( BOMなし )

BOM ありは作成できるので、バイナリモードを使用して先頭3バイトを取り去る処理を追加しています
'****************************************
' shift_jis から utf8n( BOMなし )
'****************************************

Set Fso = CreateObject( "Scripting.FileSystemObject" )
Set Stream1 = CreateObject("ADODB.Stream")
Set Stream2 = CreateObject("ADODB.Stream")
Set Stream3 = CreateObject("ADODB.Stream")

Set objFolder = Fso.GetFolder( "res" )
Set objFiles = objFolder.Files

For each objFile in objFiles
	' フルパス
	strFullPath = Fso.GetAbsolutePathName( "res\" & objFile.Name )

	' shift_jis として開く
	Stream1.Open
	Stream1.Type = 2	' StreamTypeEnum の adTypeText(デフォルト)
	Stream1.Charset = "shift_jis"

	' shift_jis として読み込む
	Stream1.LoadFromFile strFullPath

	' utf-8 として開く
	Stream2.Open
	Stream2.Type = 2
	Stream2.Charset = "utf-8"

	' shift_jis から utf-8 に変換コピーする
	Stream1.CopyTo Stream2

	' ストリームを閉じる
	Stream1.Close

	' 開始位置を先頭にして、バイナリの扱いに変更
	Stream2.Position = 0
	Stream2.Type = 1

	' BOM なしをコピーするバイナリストリーム
	Stream3.Open
	Stream3.Type = 1

	' 先頭3バイトを読み飛ばし
	Stream2.Read(3)

	' 先頭3バイトを省いてコピー
	Stream2.CopyTo Stream3

	' UTF8N で保存
	Stream3.SaveToFile strFullPath, 2	' 上書き保存

	' ストリームを閉じる
	Stream3.Close
	Stream2.Close

Next

MsgBox("処理が終了しました")

Stream オブジェクト
Type プロパティ






タグ:VBScript charset VBS
posted by lightbox at 2019-03-07 14:51 | VBS + オブジェクト | このブログの読者になる | 更新情報をチェックする

空の zip ファイル / VBScript で作成可能

「新規作成」は、レジストリに登録されています

フォルダ内で、右クリックすると表示されるポップアップメニューには「新規作成」というメニューがありますが、これは、Windows Shell 仕様に従ってレジストリに登録された情報を元に作成されています。



この中で「圧縮 (zip形式) フォルダ」とあるメニューを実行すると、空の zip ファイルが作成されます。これをダンプすると以下のような内容になっています
          0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
--------------------------------------------------------------------------
00000000 50 4B 05 06 00 00 00 00 00 00 00 00 00 00 00 00  PK..............
00000010 00 00 00 00 00 00                                ......

504B0506
0000     ディスク情報1
0000     ディスク情報2
0000     エントリされたデータの情報1
0000     エントリされたデータの情報2
00000000 サイズ情報
00000000 データへのオフセット
0000     後続するコメントの長さ
結構単純なデータですが、これは以下のようなレジストリデータとして直接データが登録されています。

コンピューター\HKEY_CLASSES_ROOT\.zip\CompressedFolder\ShellNew


Data という名前で登録されているデータが作成されるようになっています。この仕様はこちら(英文)から確認できます

さらに、この空のzip書庫は、以下のようにしてスクリプトで作成する事もできます
Set Fso = CreateObject( "Scripting.FileSystemObject" )
Set Handle = Fso.CreateTextFile( "empty.zip", True )
EmptyData = Chr(&H50) & Chr(&H4B) & Chr(&H5) & Chr(&H6)
EmptyData = EmptyData & String( 18, Chr(0) )
Handle.Write EmptyData
Handle.Close


関連する情報

.ZIP File Format Specification( 仕様 )




タグ:書庫
posted by lightbox at 2019-03-07 13:22 | Windows | このブログの読者になる | 更新情報をチェックする

2019年03月06日


VBScript : 新しい Excel の Book を作成する



サンプルは、.xlsx で保存しています

イントラネットのWEBページで利用されるテクニックの基本的な部分です。イントラネットの場合は、フォーマットを事前に作成しておくので、Excel ブックの作成を行う事は稀ですが、簡単な運用に使う場合は新規にブックが必要になると思います

※ 複数回実行すると上書きされます

昔から、Excel.Application の扱いはけっこう厄介で、実行する毎に Quit しておくとトラブルを最低限に抑える事ができます。しかし、操作方法のルールとリカバリ方法をマニュアル化しておく事が最も重要になります( トラブル時は、非表示のままメモリに残るので、タスクマネージャからタスクの終了をする必要があります )
' ****************************
' Excel オブジェクト作成
' ****************************
Set App = CreateObject("Excel.Application")

' ****************************
' 警告を出さないようにする
' ****************************
App.DisplayAlerts = False

' ****************************
' ブック追加
' ****************************
App.Workbooks.Add()

' ****************************
' 追加したブックを取得
' ****************************
Set Book = App.Workbooks( App.Workbooks.Count )

' ****************************
' 現状、ブックにはシート一つ
' という前提で処理していますが
' 必要であれば、Book.Worksheets.Count
' で現在のシートの数を取得できます
' ****************************
Set Worksheet = Book.Worksheets( 1 )
Worksheet.Activate()

' ****************************
' Add では 第二引数に指定した
' オブジェクトのシートの直後に、
' 新しいシートを追加します。
' ****************************
Call Book.Worksheets.Add(,Worksheet)

' ****************************
' シート名設定
' ****************************
Book.Sheets(1).Name = "新しい情報"
Book.Sheets(2).Name = "予備情報"

' ****************************
' 参照
' 最後の 1 は、使用するフィルター
' の番号です
' ****************************
FilePath = App.GetSaveAsFilename(,"Excel ファイル (*.xlsx), *.xlsx", 1)
if FilePath = "False" Then
	MsgBox "Excel ファイルの保存選択がキャンセルされました"
	Wscript.Quit()
End If

' ****************************
' 保存
' 拡張子を .xls で保存するには
' Call ExcelBook.SaveAs( BookPath, 56 ) とします
' ****************************
on error resume next
Book.SaveAs( FilePath )
if Err.Number <> 0 then
	MsgBox( "ERROR : " & Err.Description )
end if
on error goto 0

' ****************************
' Excel をアプリケーションとして終了
' ****************************
App.Quit()

' ****************************
' Excel を VBScript から開放
' ****************************
Set App = Nothing

' ****************************
' オブジェクト変数を初期化
' ( 初期化しないとオブジェクト扱いされる )
' ****************************
App = Empty


MsgBox( "処理が終了しました" )

Microsoft ドキュメント

Application.GetSaveAsFilename メソッド (Excel)

Application.GetOpenFilename メソッド (Excel)

Worksheets.Add メソッド (Excel)

Workbook.SaveAs メソッド (Excel)

可能列挙型 (Excel) / SaveAs メソッド で使用する定数


関連する記事

VBScript : 既存の Excel を PDF に変換する ( Excel 2007以降 )





タグ:VBScript EXCEL
posted by lightbox at 2019-03-06 20:32 | VBS + オブジェクト | このブログの読者になる | 更新情報をチェックする

2019年03月02日


VBScript : 既存の Excel を PDF に変換する ( ExportAsFixedFormat )



単純な一覧データを出力した PDF の見本


2017/12/25 更新
Excel.Application を取得しているので、GetOpenFilename でファイルを選択できるようにしました。細かい詳細はソースコードにコメントに書き込んでいます

※ PDF は、Excel と同じ名前で拡張子を .pdf にしてスクリプトと同じフォルダに保存されます。
Excel 2007以降の Excelで名前を付けて保存で PDF に保存できますが、これはスクリプトで行うコードです。Excel 2007 を調べているとメソッド紹介されていたので、引数見た限り、 VBScriptでも動くだろうと試してみました。 ( プリンタが使える状態でないと動作しません ) ExportAsFixedFormat メソッド XlFixedFormatType 最近は、VBScript の単純コードである .vbs は Google Chrome での扱いが悪いので、.wsf で作成しています。もともと、.wsf のほうが簡単に外部ライブラリを参照したり、オブジェクトを最初から定義できるのでコードが簡潔になります。ここでは、Excel.Application 内で定義されている定数も参照して使えるようにしています。 Excel 側では、印刷設定により一行目のタイトルを常に表示するようにしたり、A4 横にして縮小したりしています。シートは二つありますが、PDF に変換すると全て出力されます。
<JOB>
<OBJECT id="Fso" progid="Scripting.FileSystemObject" />
<OBJECT id="ExcelApp" progid="Excel.Application" />
<REFERENCE guid="00020813-0000-0000-C000-000000000046" />
<SCRIPT language="VBScript">
' Wscript.Echo xlTypePDF,xlTypeXPS

' **************************************
' スクリプトのあるディレクトリの取得
' **************************************
strCurPath = WScript.ScriptFullName
Set obj = Fso.GetFile( strCurPath )
Set obj = obj.ParentFolder
strCurPath = obj.Path

' 途中で異常終了すると、Excel がプロセスに残ってしまうので表示させています。
' マウス等で Excel 本体を操作しないで下さい。
' Excel を表示させたくない場合は、以下を削除または行頭に ' でコメントにして下さい
ExcelApp.Visible = True

Dim MyBook
Dim FilePath

' ここで Excel を参照するダイアログが開きます
FilePath = ExcelApp.GetOpenFilename("Excel ファイル (*.xlsx;*.xls), *.xlsx;*.xls", 1, "Excel ファイルの選択") 
if FilePath = "False" Then 
	MsgBox "Excel ファイルの選択がキャンセルされました"
	' スクリプト終了
	Wscript.Quit()
End If

' ここで Excel に読み込んでいます
on error resume next
' Workbook を取得( スクリプトと同じディレクトリ )
Set MyBook = ExcelApp.Workbooks.Open( FilePath )
if Err.Number <> 0 then
	' 終了( 開放 )
	ExcelApp.Quit()
	Wscript.Echo Err.Description & vbCrLf & FilePath
	' スクリプト終了
	Wscript.Quit()
end if
on error goto 0

Dim aPath
Dim strFileName
Dim aExt

' Excel の名前部分を取り出して、pdf の名前部分にします
aPath = Split(FilePath, "\")
strFileName = aPath(Ubound(aPath))
aExt = Split(strFileName,".")
strFileName = aExt(0)

' スクリプトと同じフォルダに保存されます
Call MyBook.ExportAsFixedFormat( xlTypePDF, strCurPath & "\" & strFileName & ".pdf" )

' 終了( 開放 )
ExcelApp.Quit()

' 終了確認
Wscript.Echo "処理が終了しました"

</SCRIPT>
</JOB>


Microsoft の記事

Application.GetOpenFilename メソッド

Microsoft の英文の記事

Saving Workbooks to PDF and XPS Formats in Excel 2007




タグ:VBScript EXCEL PDF
posted by lightbox at 2019-03-02 17:39 | VBS + オブジェクト | このブログの読者になる | 更新情報をチェックする

JavaScript の内部コード文字列を SHIFT_JIS としてダウンロードさせる方法

SyntaxHighlighter カスタマイズ

SyntaxHighlighter のツールバーの右端のアイコンでファイルをダウンロードさせると、テキストのキャラクタセットは UTF-8 になります。通常はそれでもいいのですが、VBScript をダウンロードしてもらう場合は SHIFT_JIS である必要があるので、なんとかならないかと調べてみてすぐ見つけたのが

javascriptで文字コード変換

という Qiita の記事でした。その中で紹介されている ecl.js は、自分も以前使った事があったのですが、バイナリデータとして変換する目的では無いと記憶していました。ですが、一応記事の冒頭にあるコードでテストしてみましたがうまく行かず、Encoding.js のほうを使用して目的を達成しました。

Encoding.js

元々、バイナリの配列にデータを格納して変換しているので、文字列からの変換処理さえあればすぐ使えます。その関数は、Qiita の記事に既に紹介されていたのでとても簡単に実装する事ができました。

実装では、改行コードの扱いに留意して下さい。

サンプルコード
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.8/FileSaver.min.js"></script>
<script src="https://winofsql.jp/js/encoding.js"></script>
<script src="https://winofsql.jp/js/save-sjis.js"></script>

<script>
$( function(){

	$("#save-action").on("click", function(){

		// テキストエリアのテキストを jQuery で取得		
		var text = $("#save-text").val();
		// lf のみを crlf に変換
		text = text.replace(/\n/g, '\r\n');
		// ローカルに保存する
		save_sjis( "save-sjis.txt", text );
	});

});
</script>
<div><input type="button" id="save-action" value="Save as Shift_JIS"></div>
<textarea id="save-text" style='width:400px;height:100px;'></textarea>


▼ save-sjis.js
var str2array = function(str) {

	var array = [],i,il=str.length;
	for(i=0;i<il;i++) array.push(str.charCodeAt(i));
	return array;

};

function save_sjis( filename, str ) {

	var array = str2array( str );
	var sjis_array = Encoding.convert(array, "SJIS", "UNICODE");
	var sjis_data = new Uint8Array(sjis_array);

	saveAs(
		new Blob(
			[sjis_data]
			, {type: "text/plain;charset=shift_jis"}
		)
		, filename
	);

}


▼ こちらでテストして下さい
( サンプルコードのソースを copy ボタンでコピーしてリンク先で貼り付けて実行して下さい)

関連する記事

ブラウザ上のテキストデータを名前を付けて保存できる FileSaver.js を使って、テーブルのデータを Excel で開ける事を想定した CSV にして PC に保存

ファイルを JavaScript から保存する FileSaver.js

FileSaver.js は saveAs メソッドを提供します。ダウンロードする必要は無く、cdnjs でホスティング されています。

Uint8Array


posted by lightbox at 2019-03-02 13:40 | JavaScript ライブラリ | このブログの読者になる | 更新情報をチェックする

2019年03月01日


VBScript( WMI )によるイベント関数を WMI に登録するタイマー処理

VBScript(WSH) の WScript.CreateObject では、作成したオブジェクトのイベントを受け付ける関数を定義する事ができます。過去、ほとんどそのようなサンプルは現実には無かったのですが、WMI では少なくともタイマー処理として利用可能です。

CreateObject メソッドstrPrefix 引数を指定すると、接続されたオブジェクトが作成されます。

これは、オブジェクトのイベントを同期させる場合に便利です。オブジェクトの出力インターフェイスは、オブジェクト作成後にスクリプト ファイルに接続されます。

イベント処理関数は、このプリフィックスとイベント名を組み合わせた名前になります。オブジェクト作成時に strPrefix 引数を指定しなかった場合は、ConnectObject メソッドを使ってオブジェクトのイベントを同期させることができます。オブジェクトがイベントを発行すると、WSH は strPrefix + イベント名という形式の名前を持つサブルーチンを呼び出します。

たとえば、strPrefix が MYOBJ であり、オブジェクトが OnBegin というイベントを発行した場合、Windows Script Host はスクリプト内の MYOBJ_OnBegin という名前のサブルーチンを呼び出します
タイマー処理
' ********************************************************************
' このセクションは、cscript.exe で処理を強制させるものです
' ********************************************************************
str = WScript.FullName
str = Right( str, 11 )
str = Ucase( str )
if str <> "CSCRIPT.EXE" then
	str = WScript.ScriptFullName
	Set WshShell = CreateObject( "WScript.Shell" )
	Call WshShell.Run( "cmd.exe /c cscript.exe """ & str & """ & pause", 3 )
	WScript.Quit
end if

' ********************************************************************
' 秒単位のログを表示するかどうかのフラグです
' ********************************************************************
Dim Disp : Disp = True	' False にすると、秒単位の表示はしなくなります

' ********************************************************************
' WMI のイベントの定義
' ********************************************************************
Set SINK = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
objWMIService.ExecNotificationQueryAsync _
 SINK, _
 "SELECT * FROM  __InstanceModificationEvent " & _
 "WHERE TargetInstance ISA 'Win32_LocalTime'"

Wscript.Echo "タイマー処理を開始します"
' ********************************************************************
' 停止する為のイベントの定義
' ********************************************************************
Set objMonitor = objWMIService.ExecNotificationQuery( _
	"select * from __InstanceModificationEvent " & _
	"where TargetInstance isa 'Win32_LocalTime' " & _
	" and TargetInstance.Year = 0" _
)

' Wscript.Echo "TargetInstance.Year は 0 にならないので、次の行より後の処理は実行されません"
Set objLatestEvent = objMonitor.NextEvent 
Wscript.Echo "ここは実行されません"

' ********************************************************************
' この処理は、WbemScripting.SWbemSink から呼び出されます
' ********************************************************************
Sub SINK_OnObjectReady(objLatestEvent, objAsyncContext)

	' 10秒毎の処理
	if objLatestEvent.TargetInstance.Second MOD 10 = 0 then
		' ここが 10秒毎に呼び出されます
		Wscript.Echo "秒の余りが 0 の場合にここが実行されます"
		Wscript.Echo "分や時間を使用すると、長いスパンの定期処理に使えます"
	end if

	if Disp then
		' 秒単位に呼び出されるこのルーチンで毎回表示
		Wscript.Echo "Time: " & _
			objLatestEvent.TargetInstance.Hour & ":" & _
			objLatestEvent.TargetInstance.Minute & ":" & _
			objLatestEvent.TargetInstance.Second
	end if
End Sub






posted by lightbox at 2019-03-01 13:29 | VBS + WMI | このブログの読者になる | 更新情報をチェックする
container 終わり



フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり