SQLの窓

2019年01月28日


VBScript : キーストロークをウインドウに送信して、キー操作をした事にする( 例 : リモート デスクトップ接続ダイアログ )

リモート デスクトップ接続は開いた後、詳細画面が表示されないので、ALT+O を送り、その後 SHIFT+TAB でタブを選択して、右矢印で次のタブに移動させます。
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run( "mstsc.exe" )

WScript.Sleep(500)
WshShell.AppActivate("リモート デスクトップ接続")
WScript.Sleep(500)

' キーストロークを送信
WshShell.SendKeys ("%O")
WScript.Sleep(500)
WshShell.SendKeys ("+{TAB}")
WScript.Sleep(500)
WshShell.SendKeys ("{RIGHT}")

※ キーストロークの送信は環境や状況によっては、うまく動作しないかもしれません。その場合は適宜変更して下さい(キーストローク詳細)




タグ:VBScript
posted by lightbox at 2019-01-28 17:17 | VBS + Shell | このブログの読者になる | 更新情報をチェックする

販売管理 (2)

業務フロー

業務フローはその名の通り業務の流れを図解したものです。その中にはコンピュータの操作が発生するタイミング以外に、人間が実際に作業する内容も含まれています。

例えば、売上を発生させる為には商品が必要です。その商品は他の企業から仕入れるかもしれませんし、倉庫にある在庫から取り出すかもしれません。そして、その商品を必要とする顧客に引き渡す為には、誰かが届ける必要があり、届けた場合に相手が受け取ったという証明が必要になります。

これを販売管理に必要な事実として流れとして繋げると一例として以下のようになります。
出庫 => 納品伝票作成 => 輸送 => 納品 => 受領書受取り => 売上確定 
まだこの前後に必要な販売活動のバリエーションがありますが、【売る】と言う事実だけを取り出すとこのようになります。企業は、この流れを日々繰り返して売上を蓄積させて締めというタイミングで合計して請求と言う作業を行います。 締め処理 締めのタイミングは取引では立場の強い支払い側が決定します。つまり、売る側からすると納品先毎に締めのタイミングが違う事になりますが、期間は管理上必ず1か月となります。 販売活動として、締めの日付の次の日から次の締めの日までの売上を合計して請求書を作成します。その請求書を何らかの方法で請求先に届ける必要があるので、得意先(支払い側)がその内容を確認するのは少し先になります。 支払い 得意先側も販売活動の一環としてその請求書の内容を確認する必要があります。その請求書に該当する期間に納品された商品の納品書の内容と請求書の明細とが一致するかを確認した上で、支払処理の準備をする必要があります。 支払い側は、他の仕入先も同じ締め日になるので、全ての支払う必要のある買掛金の合計を販売管理のシステムで合計する事ができます。そして、支払時期に合わせて現金やその他の支払う為に必要な対価を準備します。この作業を一般的に資金繰りと言います。この資金繰りの状況によっては、銀行に融資をしてもらったりする事もあり、最悪資金が調達できなければ企業が負債を抱えて倒産する事もあります。 単純には、売上げてもすぐ現金が入ってこない掛け売りという形態であり、さらに支払いに関して言えば通常締めの期日より1か月以上後に支払われる事は一般的です。なので資金繰りという重要な販売活動をする上で、売上支払の金額を正確に知って分析する為に販売管理システムは販売活動の大きな助けとなります。 入金種別 企業の一般的な支払方法は銀行振込になります。その場合、振込手数料は慣習的に請求書を発行する側の負担になる事が多いようですが、支払側が事前の取り決めで負担してくれる場合もあります。 昔は集金という業務があり、現金で支払ってもらう為に直接出向いて現金を受け取るという形態もありましたが、今ではリスクが大きいのである程度の規模の企業が利用する事は稀だと思われます。 現金にやや近い形態が小切手による支払いです。小切手を利用するには当座預金が必要で、降り出した小切手を受け取った側が銀行に出向くという手間が必要になります。現金を持ち歩くリスクは無くなりますが、盗難のリスクは残ります。そして、銀行にある口座に預け入れてもらうか現金で受け取る事になるので、リスクを考えれば得意先の取引銀行に口座を持つ必要があります。 当座預金口座を持っておれば、支払い方法として手形を選択可能になります。手形に関する詳細はさらに複雑ですが、販売管理とは直接つながりません( 在庫管理のように大きな範囲では関連します ) 特殊な条件下では相殺という入金の種類があります。ある取引先が得意先にも仕入先にもなる場合、売掛金と買掛金が同時に発生する場合があります。その場合実際の現金の動きが必要無い場合は相殺という形で売掛金と買掛金を消滅させる方法です。この場合、販売管理で入金した場合は支払いも同時に発生する事になるので、ユーザができるだけ簡単に処理できるように考える必要があります。 金融機関を使う方法でもう一つ利用可能な決済方法があり、口座振替と呼ばれています。これは支払い側と同じ銀行に口座を持つ事によって、手続きだけで現金を移動させる方法です。これは、金融機関内の現金は変化せずに、持ち主のみが変わるので手数料が必要無いのが通常となります。
posted by lightbox at 2019-01-28 16:56 | システム開発 | このブログの読者になる | 更新情報をチェックする

販売管理 (1)

販売管理システム

販売管理は、企業が利益を上げる為の活動として一般的に行われる手順をコンピュータの中で行う場合のシステムのジャンルです。

コンピュータが無い状態での販売活動の基本は、に記録する事です。それらは伝票であったり台帳であったりメモ書きであったりしますが、に記録する代わりにコンピュータの外部記憶装置に記録し、正しい事実や数字の管理をする事が大きな目的です。

その為に必要な手順として、まずシステム側とユーザ側でその企業における販売活動の詳細を整理する必要があります。その中で最もユーザ側が理解しやすい形でシステム側が提供すべきなのは【入力】と【出力】です。具体的には、【入力】はコンピュータの画面であり、【出力】はもともとは紙で記録されていたものです。そして、それらは専門的には画面設計帳票(表)設計と呼ばれるもので、最終的にユーザ側が最も必要なものは『印刷されるもの』であって、それはである事が殆どです。


掛売り

企業の販売活動の要点は掛売りと言う取引で行われるところです。

掛売りとは、一般消費者が利用する店舗における現金との引換えでは無く、商品の対価の受け取りを一定期間の後に行う方法です。

簡単に言えば後払いで商品を売ることで、支払うという立場を一般消費者から見ればクレジットカード払いが似たように見えます( クレジットカード払いでは実際にはクレジットカード会社が先に払い、一般消費者はクレジットカード会社に支払うという形態で同じではありません )


売掛金

そして、この方法による販売の対価の蓄積を売掛金と呼び、売掛と言う言葉は掛け売りとほぼ同じ意味に使用されます。

売掛金という言葉は簿記仕訳の際にも使用されます。
【借方】売掛金:1,000 / 【貸方】売上:1,000
売上売掛金は対を成す事になり、売掛金は経理上重要な言葉となりますが、販売管理としては売上と言う言葉で商品を納品した時点で積み上がります。そして、売掛金1,000円が振込みで支払われた場合は以下のような仕訳になります
【借方】普通預金:1,000 / 【貸方】売掛金:1,000
販売管理では、この支払われた売掛金を入金処理によって、入金の日付種別(この場合は振込)と入金額をコンピュータに記録します。つまり、販売管理では売上と入金という現実に起こった事実に対して管理情報を記録します。それに対して売掛金という言葉は販売管理の中では使用せず、経理のシステムで使用される事になります。 企業の販売活動の目的は利益を上げる事なので、直接的に必要な事実は売上と入金です。しかし、実際の販売活動にはこれ以外の事実が発生するので、販売管理ではそれらを全て管理しなければなりません。そして、どのような事実が発生するかをユーザ側とシステム側で同じ認識にする手法として業務フローの作成があります。
posted by lightbox at 2019-01-28 12:20 | システム開発 | このブログの読者になる | 更新情報をチェックする

2019年01月25日


VBScript を使って HTTPプロトコルで PHP へファイルをアップロードする方法


関連する記事

ファイルのアップロード時のデータのダンプ

仕様を確認したわけではありませんが、boundary は、境界識別する為のユニークな文字列であると思われます。http ヘッダで指定した文字列を x とすると --x が境界で、改行コードが付加されます。一番最後の境界は --x-- です。
upload_target.php ※ upload_target.php と同じ場所にアップロードされたファイルを作成します。
<!DOCTYPE html>
<html>
<head>
<title>単純ファイルアップロード</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css">
<style>
#content,#result {
	padding: 20px;
}
#result {
	white-space: pre;
}
</style>
</head>
<body>
<div id="content">
	<form
		enctype="multipart/form-data"
		method="POST">
	
		<p>
			<input name="target" type="file" class="ml-4 btn btn-outline-primary">
			<a
				class="ml-4 btn btn-info btn-sm"
				href="<?= $_SERVER["PHP_SELF"] ?>">GET 再読み込み</a>
		</p>
		<p>
			<input type="submit" name="send" value="アップロード" class="ml-4 btn btn-outline-primary">
		</p>
	 
	</form>
</div>
<div id="result">
<?php
if ( $_SERVER['REQUEST_METHOD'] == "POST" ) {
 
	$upload = realpath("./");
	$upload .= ( DIRECTORY_SEPARATOR . $_FILES['target']['name'] );

	print "$upload\n";

	if ( move_uploaded_file($_FILES['target']['tmp_name'], $upload ) ) {
		print "<p>アップロードに成功しました</p>\n";
	}

	print_r( $_FILES );
}

?>
</div>
</body>
</html>


upload.wsf

アップロード先の情報と、アップロードするファイルの情報を『アップロード用 URL』セクションで書き換えて下さい。

テキストストリームに shift_jis をセットしていますが、この場合 VBScript 側も PHP 側も日本語のインターフェイスを使用していないので問題ありません。( テキストを UTF-8 で送りたい場合は同様の方法で shift_jis を UTF-8 に変換する方法はありますが、PHP 側で変換するほうが簡単でしょう )
<JOB>
<COMMENT>
************************************************************
 URLEncode用
************************************************************
</COMMENT>
<OBJECT id="Stream" progid="ADODB.Stream" />
<OBJECT id="StreamWorkBin" progid="ADODB.Stream" />
<OBJECT id="StreamBin" progid="ADODB.Stream" />
<COMMENT>
************************************************************
 HTTP通信用
************************************************************
</COMMENT>
<OBJECT id="objHTTP" progid="Msxml2.ServerXMLHTTP" />

<SCRIPT language=VBScript>

' **********************************************************
' アップロード用 URL
' **********************************************************
upload_url = "http://localhost/test/001/upload_target.php"
upload_file = "winofsql.png"
upload_type = "image/png"

' *********************************************************
' 送信準備
' *********************************************************
Call objHTTP.Open( "POST",upload_url, False )
' File Upload 用 HTTP ヘッダ
strBoundary = DateDiff("s", "1970/1/1 0:00:00",DateAdd("h",-9,now))
Call objHTTP.setRequestHeader("Content-Type", "multipart/form-data; boundary="&strBoundary)

' バイナリ変換用ストリーム
StreamWorkBin.Open
StreamWorkBin.Type = 1

' 最終バイナリストリーム
StreamBin.Open
StreamBin.Type = 1

' テキストストリーム
Stream.Open
Stream.Charset = "shift_jis"

' 開始セクション
Stream.WriteText "--" & strBoundary & vbLf
Stream.WriteText "Content-Disposition: form-data; name=""target""; filename=""uploadtest.png""" & vbLf
Stream.WriteText "Content-Type: "&upload_type& vbLf
Stream.WriteText vbLf
Stream.Position = 0

' テキストをバイナリに変換
Stream.CopyTo StreamWorkBin

' 第一セクションを書き込み
StreamWorkBin.Position = 0
StreamBin.Write StreamWorkBin.Read(StreamWorkBin.Size)

' 画像を読み込む
StreamWorkBin.LoadFromFile(upload_file)

' 画像を書き込み
StreamBin.Write StreamWorkBin.Read(StreamWorkBin.Size)

' バイナリワークをいったん閉じる
StreamWorkBin.Close
StreamWorkBin.Open
StreamWorkBin.Type = 1

' テキストをいったん閉じる
Stream.Close
Stream.Open
Stream.Charset = "shift_jis"

' 終了セクション
Stream.WriteText vbLf & "--" & strBoundary & "--" & vbLf
Stream.Position = 0

' テキストをバイナリに変換
Stream.CopyTo StreamWorkBin

' 終了セクションを書き込み
StreamWorkBin.Position = 0
StreamBin.Write StreamWorkBin.Read(StreamWorkBin.Size)

' 送信データを取得
nLen = StreamBin.Size
StreamBin.Position = 0
strData = StreamBin.Read(nLen)

Call StreamBin.SaveToFile( "result.dat", 2 )

' *********************************************************
' 投稿データとその長さ
' *********************************************************
Call objHTTP.SetRequestHeader("Content-Length",nLen)

' *********************************************************
' API へ向けて送信
' *********************************************************
Dim lResolve : lResolve = 60 * 1000
Dim lConnect : lConnect = 60 * 1000
Dim lSend : lSend = 60 * 1000
Dim lReceive : lReceive = 60 * 1000
Call objHTTP.setTimeouts(lResolve, lConnect, lSend, lReceive)
Call objHTTP.Send(strData)

Wscript.Echo(objHTTP.responseText)


</SCRIPT>
</JOB>

result.dat には、アップロードする為にサーバに転送したデータ部分がそのまま保存されます。





タグ:Curl
posted by lightbox at 2019-01-25 16:45 | VBS + インターネット | このブログの読者になる | 更新情報をチェックする

2019年01月24日


PHP の cURL でファイルアップロード

cURL を使うとWEBの通信部分の面倒な部分( ssl や ファイルアップロード ) を簡単に処理してくれます。ここで、file-upload.php は、WEB サーバー上ですが、upload.php は、Windows のローカルPC から、コマンドプロンプトで php.exe upload.php で実行可能です

※ 昔と違って、CURLFile クラス を使わないとファイルをアップロードできません

※ MIME 情報は Fileinfo 関数 で取得しています。

関連する記事

VBScript から PHP へファイルアップロード
PHP : cURL で FTP + SSL ダウンロード

file-upload.php
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>ファイルアップロードの簡易テンプレート</title>
</head>
<body>
<form 
	enctype="multipart/form-data"
	method="POST">
 
	アップロードするファイル : 
	<input name="target" type="file">
	<p><input type="submit" value="アップロード"></p>
 
</form>
<pre>
<?php
if ( $_SERVER['REQUEST_METHOD'] == "POST" ) {

	// アップロードするフォルダ
	$upload = realpath ( "./image" );
	// アップロードするファイル
	$upload .= ( "\\" . str_replace( "%", "", urlencode( $_FILES['target']['name'] ) ));
	// 一時ファイルをアップロードファイルとして移動
	if ( move_uploaded_file(
		$_FILES['target']['tmp_name'], $upload ) ) {
		print "アップロードに成功しました<br>\n";
	}

	// アップロード情報の表示
	print_r( $_FILES );

}

?>
</pre>
</body>
</html>


upload.php
<?php
// ***************************************************
// curl 処理
// ***************************************************
$url = "http://localhost/lightbox/20190124/file-upload.php";

$curl = curl_init();
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, $url);

// POST ( デフォルトは GET )
curl_setopt($curl, CURLOPT_POST, true);

// アップロードするファイル
$path = 'lightbox.jpg';

// Windows では extension=php_fileinfo.dll が必要
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $path);
finfo_close($finfo);

// CURLFile クラスのコンストラクタ
// 1) 実際のファイルのパス
// 2) ファイルの MIME
// 3) アップロード先に渡すファイル名
$data = array( 'target' => new CURLFile($path, $mime, 'lightbox-upload.jpg') );
curl_setopt($curl, CURLOPT_POSTFIELDS, $data );

// ***************************************************
// デバッグ用
// ***************************************************
curl_setopt($curl, CURLOPT_VERBOSE, true);	

$handle1 = fopen("./debug.txt", "w");
curl_setopt($curl, CURLOPT_STDERR, $handle1);

$handle2 = fopen("./ret_header.txt", "w");
curl_setopt($curl, CURLOPT_WRITEHEADER, $handle2);

// ***************************************************
// SSL
// ***************************************************
if ( substr( $url, 0, 5 ) == "https" ) {
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
}

// ***************************************************
// 送信
// ***************************************************
$result = curl_exec($curl);

// ***************************************************
// 結果
// ***************************************************
if($result === false) {
	$result = 'Curl error: ' . curl_error($curl);
}
curl_close($curl);
fclose($handle2);
fclose($handle1);

print( $result . "\n" );

?>





タグ:Curl
posted by lightbox at 2019-01-24 16:34 | PHP + 通信 | このブログの読者になる | 更新情報をチェックする

2019年01月21日


PHP : WEB でもコマンドラインでも HTTP でファイルをダウンロードする 『fget.php』

fopen wrappers が有効の場合、WEB 上で配置するとそのサーバー以外の別のサーバにあるファイルを http 経由でいったん読み込んでからクライアントへ送ります。その際、ファイルサイズが必要になるので、readfile に先立って、cURL で、ファイルサイズだけを取得しています。

readfile はこのような処理に使う為の関数ですが、標準出力へ内容を出力するのでコマンドプロンプトで使う場合はファイルへリダイレクトする必要があります。なので、ここではコマンドプロンプトの場合は readfile を使用せずに通常のファイル処理としてファイルを書き込んでいます。

fget.php
<?php
// **************************************************
// 【fget.php】
// http:// で他のサーバのファイルを読み込んでダウンロードします
// 【利用方法】
// WEB : fget.php?target=URLエンコードされたURL&name=保存ファイル名
// CMD : 1) php.exe fget.php URL
// CMD : 2) php.exe fget.php URL 保存ファイル名
// **************************************************

// **************************************************
// コマンドラインでも使えるように
// **************************************************
if (substr(php_sapi_name(), 0, 3) == 'cgi') {
	$remoteFile = $_GET['target'];
}
else {
	$remoteFile = $argv[1];
}

// 保存ファイル名をパスから作成
$fileName = basename($remoteFile);

// 保存ファイル名を指定した場合
if (substr(php_sapi_name(), 0, 3) == 'cgi') {
	// WEBアプリで 保存ファイル名を指定
	if ( isset($_GET['name']) ) {
		$fileName = $_GET['name'];
	}
}
else {
	// コマンドプロンプトで 保存ファイル名を指定
	if ( isset($argv[2]) ) {
		$fileName = $argv[2];
	}
}

// **************************************************
// PHP オンラインマニュアルの投稿データより
// ファイルのサイズを取得する cURL の処理
// **************************************************
$ch = curl_init($remoteFile);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if ( substr( $remoteFile, 0, 5 ) == "https" ) {
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
}
$data = curl_exec($ch);
curl_close($ch);
if ($data === false) {
	echo 'cURL failed';
	exit;
}

$contentLength = 'unknown';
$status = 'unknown';
if (preg_match('/^HTTP\/1\.[01] (\d\d\d)/', $data, $matches)) {
	$status = (int)$matches[1];
}
if (preg_match('/Content-Length: (\d+)/', $data, $matches)) {
	$contentLength = (int)$matches[1];
}

// **************************************************
// WEB 経由ダウンロード
// **************************************************
if (substr(php_sapi_name(), 0, 3) == 'cgi') {
	header( "Content-Type: application/octet-stream" );
	header( "Content-disposition: attachment; filename={$fileName}" );

	$path = $remoteFile;

	header( "Content-Length: $contentLength" );

	readfile($path);

	exit();
}
// **************************************************
// Windows コマンドライン
// Windows では、fopen()の mode パラメータに 'b' を
// 指定してファイルをオープンする必要があります。
// **************************************************
else {
	$ihandle = fopen($remoteFile, "rb");
	$ohandle = fopen($fileName, "wb");
	if ( $ihandle ) {

		while( !feof($ihandle) ) {
			$ret = fread( $ihandle, 1024 );
			fwrite( $ohandle,  $ret );
		}

		fclose( $ohandle );
		fclose( $ihandle );
	}

	exit();
}

?>


関連する情報

PHP fread

fread の第二引数は、読み込む最大バイトなので、EOF に達すると、それ以内のデータが取得されます。

PHP fwrite

大きなファイルですと、問題が出るという報告もあるので、その場合は以下のように readfile を書き換えるといいかもしれません。

Streaming a large file using PHP

Problem with download of larger files





posted by lightbox at 2019-01-21 16:12 | PHP + 通信 | このブログの読者になる | 更新情報をチェックする
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 終わり