SQLの窓

2019年03月19日


コマンド リダイレクト演算子を使用する( Using command redirection operators )

✅ Microsoft ドキュメント
コマンド リダイレクト演算子を使用する

⭐ 単純な リダイレクト は > です。
 コマンドプロンプトに表示されるはずの文字列をファイルに書き込みます。

⭐ >> を使うと追加書き込みです。

このような記号は、リダイレクト演算子と呼ばれます。

STDIN

0

キーボード入力

STDOUT

1

標準出力

標準エラー出力

2

Error output to the Command Prompt window

0、1、2 は ハンドル番号で、既存のハンドルへのリダイレクトを指定するには、アンパサンド(&)文字の後にリダイレクトしたいハンドル番号を使用します。

なので、2>&1 は 標準エラー出力を標準出力にリダイレクトする事を意味します。

▼ 解りやすいテストはエラーだけに着目して、以下のように実行します。
C:\temp>dir x
 ドライブ C のボリューム ラベルは Windows10 です
 ボリューム シリアル番号は 40B9-7D17 です

 C:\temp のディレクトリ

ファイルが見つかりません
( x が存在しないので『ファイルが見つかりません』と言うエラーメッセージが出ます ) この『ファイルが見つかりません』は、dir x > message.txt としても message.txt には書き込まれまれずに、コマンドプロンプトに表示されます。 しかし、以下のようにすれば全て書き込む事ができます。
dir x > message.txt 2>&1
この方法は解りにくいですが、標準出力と標準エラー出力を同時にリダイレクトしたいときに意味があります。
dir x 2> message.txt
だと、ファイルが見つかりません だけが書き込まれてしまいます。 キーボード入力をファイル化 リダイレクト演算子を使用して、キーボードから入力した文字列をテキストファイルに書き込む事ができます。
type con > message.txt
type コマンドは、ファイルの内容をコマンドプロンプトに表示するコマンドですが、con と言う特殊な予約文字列を使用すると、キーボードをファイルとみなした動作を行います。 ※ 終了時は 改行入力後、CTRL+Z を入力してEnter です 空のファイルを作成する nul と言う予約文字列を使用して以下のように実行します
type nul > message.txt
実行結果を表示しない nul は存在しないファイルのようなものなので、標準結果への出力を無かった事にできます
dir *.* > nul
posted by lightbox at 2019-03-19 14:26 | コマンドプロンプト | このブログの読者になる | 更新情報をチェックする

C# : SQL 文を外部テキストにして、String.Format でデータ部分を置き換えて利用する

基本的には、String.Format メソッドのお話ですが、文字列の配列の扱いとの関係での注意事項です。
-- ******************************
-- 社員マスタ更新
-- ******************************
 
UPDATE 社員マスタ
set
氏名 = '{1}',
給与 = {2},
-- 行コメント
生年月日 = {3}

--
 
where 社員コード = '{0}'
 
-- 行コメント
行コメントは、正規表現で削除します。{} 部分の個数より、配列が大きい必要があり、Nothing が指定されると、{} ごとなくなります。
※ 配列のリサイズが必要な場合は、Array.Resize メソッドで行います。


C# による記述
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace text_input
{
	class Program
	{
		static void Main(string[] args)
		{
			// 入力ファイルのパス
			string[] arguments = Environment.GetCommandLineArgs();
			// 引数は一つのみ許可
			if (arguments.Length != 2)
			{
				Console.WriteLine("引数を指定して下さい");
				return;
			}

			// 引数から取得
			string filePath = arguments[1];

			// パスを表示
			Console.WriteLine(filePath);

			// *********************************
			// ▼ 関数呼び出しを記述して、ALT + Enter で自動作成
			// *********************************
			string textData = loadTextData(filePath);

			// *********************************
			// 行コメントの削除
			// ▼ 正規表現のオプション
			// https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/regular-expression-options
			// *********************************
			string pattern = "(?m)^--.*";   // 複数行モード
			textData = System.Text.RegularExpressions.Regex.Replace(textData, pattern, "");

			Console.Write(textData);

			// *********************************
			// 配列の準備(1)
			// *********************************
			string[] data1 = { "0001", "山田太郎", "100000", "'1980/01/01'" };
			Console.WriteLine("配列の数は {0} です", data1.Length);

			// *********************************
			// 配列を文字列内に埋め込む
			// *********************************
			string sqlResult = String.Format(textData, data1);
			Console.Write(sqlResult);

			// *********************************
			// 配列の準備(2)
			// *********************************
			string[] data2 = new string[4];
			data2[0] = "0002";
			data2[1] = "山田花子";
			data2[2] = "20000";
			data2[3] = "NULL";

			// *********************************
			// 配列を文字列内に埋め込む
			// *********************************
			sqlResult = String.Format(textData, data2);
			Console.Write(sqlResult);

			// *********************************
			// 配列の準備(3)
			// *********************************
			string[] data3 = new string[4];
			data3.SetValue("0003", 0);
			data3.SetValue("山田美子", 1);
			data3.SetValue("30000", 2);
			data3.SetValue("'1980/01/01'", 3);

			// *********************************
			// 配列を文字列内に埋め込む
			// *********************************
			sqlResult = String.Format(textData, data3);
			Console.Write(sqlResult);

			// *********************************
			// 配列の準備(4)
			// *********************************
			List<string> data4 = new List<string>();
			data4.Add("0004");
			data4.Add("山田史郎");
			data4.Add("40000");
			data4.Add("'1990/01/01'");

			// *********************************
			// 配列を文字列内に埋め込む
			// *********************************
			sqlResult = String.Format(textData, data4.ToArray());
			Console.Write(sqlResult);

			// *********************************
			// 配列の準備(5)
			// ※ 追加するデータ型自由
			// *********************************
			ArrayList data5 = new ArrayList();
			data5.Add("0005");
			data5.Add("山田吾郎");
			data5.Add(50000);
			data5.Add(new DateTime(1995, 1, 1));

			// *********************************
			// 配列を文字列内に埋め込む
			// 混在なので object 配列
			// *********************************
			object[] strWork = data5.ToArray();
			sqlResult = String.Format(textData, strWork[0], strWork[1], strWork[2], $"'{strWork[3]}'");
			Console.Write(sqlResult);

			Console.ReadLine();

		}

		private static string loadTextData(string filePath)
		{

			string text = "";

			// *********************************
			// 主なエンコード
			// *********************************
			// SHIFT_JIS
			// Encoding Enc = Encoding.GetEncoding(932);
			// EUC-JP
			//Encoding Enc = Encoding.GetEncoding(51932);
			// UNICODE 用
			//Encoding Enc = Encoding.GetEncoding(1200);
			// UTF-8N
			Encoding Enc = new UTF8Encoding();
			// UTF-8
			//Encoding Enc = new UTF8Encoding(true);

			// プロック終了時に開放
			try
			{
				using (StreamReader ReadFile = new StreamReader(filePath, Enc))
				{
					// 読込み
					text = ReadFile.ReadToEnd();

					// 全て読み込んでいるので閉じる
					ReadFile.Close();

					Console.Write(text);
				}

			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message);
			}

			return text;

		}
	}
}

引数は、プロジェクトのプロパティからデバッグタブを開けて設定します。





posted by lightbox at 2019-03-19 09:48 | VS(C#) | このブログの読者になる | 更新情報をチェックする

2019年03月13日


C# コンソールアプリを AN HTTPD で実行

テストにはまだまだ使える(重宝する) AN HTTP Server の正しい使用方法

単純に、WEB アプリケーション初心者にブラウザとサーバーのやり取りを知ってもらう為に( 今は、開発者ツールがあるので途中の解説がしやすいですし )、C# で作った EXE をそのままブラウザで実行させます。

基本設定

EXE の列の『一般パスでも実行する』にチェックします



次に、一般パスに C# で作成された Debug フォルダを登録します。



後は、loclhost から実行するだけです。

ソースコード
using System;
using System.Collections;
using System.Text;
using System.Web;

namespace cgi_test
{
	class Program
	{
		static void Main(string[] args)
		{
			string formtype = "POST";

			string[] param = { };

			// ******************************
			// Console.WriteLine を UTF8 で
			// ******************************
			Console.OutputEncoding = Encoding.UTF8;

			// ******************************
			// メソッド
			// ******************************
			string method = Environment.GetEnvironmentVariable("REQUEST_METHOD");

			// ******************************
			// GET
			// ******************************
			if (method == "GET")
			{
				// ******************************
				// QUERY_STRING
				// ******************************
				string query_string = System.Environment.GetEnvironmentVariable("QUERY_STRING");
				// URL のみの場合はデータ無しの QUERY_STRING を用意する
				if (query_string == "" )
				{
					query_string = "field1=&field2=";
				}

				// & で分割して key=value の文字列の配列を作成する
				param = query_string.Split('&');
			}

			// ******************************
			// POST
			// ******************************
			if (method == "POST")
			{
				string line;

				// POST 時は必ず key=value の文字列が存在する
				line = Console.ReadLine();
				param = line.Split('&');
			}

			// = で区切って key と value が配列の 0 と 1 にセットされる
			string[] key_value = { };

			// ******************************
			// key と value の格納
			// ******************************
			Hashtable field = new Hashtable();

			foreach (string key_value_set in param)
			{
				key_value = key_value_set.Split('=');
				// key がある場合は、Hashtable に格納する
				if (key_value[0] != "") {
					// System.Web を参照して using System.Web; で HttpUtility.UrlDecode
					// %エンコードを元に戻す
					field.Add(key_value[0], HttpUtility.UrlDecode(key_value[1]));
				}
			}

			// ******************************
			// HTTP ヘッダ
			// PHP の session_cache_limiter
			// ******************************
			Console.WriteLine("Content-Type: text/html; charset=utf-8");
			Console.WriteLine("Expires: Thu, 19 Nov 1981 08:52:00 GMT");
			Console.WriteLine("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
			Console.WriteLine("Pragma: no-cache");
			Console.WriteLine();

			string message = "<div>こんにちは世界</div>";

			// ******************************
			// HTML
			// $ で変数埋め込みのヒアドキュメント
			// ******************************
			string html = $@"<!DOCTYPE html>
<html>
<head>
</head>
<body>
{message}
<form method='{formtype}'>
<p>氏名 : <input type='text' name='field1' value='{field["field1"]}'></p>
<p>フリガナ : <input type='text' name='field2' value='{field["field2"]}'></p>
<p>送信 : <input type='submit' name='send' value='送信'></p>
</form>
</body>
</html>";

			// 作成した HTML を出力する
			Console.WriteLine(html);
		}
	}
}





posted by lightbox at 2019-03-13 22:02 | VS(C#) | このブログの読者になる | 更新情報をチェックする

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月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 + オブジェクト | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します
container 終わり



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

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