カテゴリ:プログラミング( 102 )
[VBScript] ドラッグ&ドロップ処理ツールのテンプレート
こんにチワワ。どーもボキです。

VBSファイル(または、ショートカット)にドロップされたファイルを処理するスクリプト。
フォルダがドロップされた場合は、サブフォルダも含め、そのなかのすべてのファイルを処理する。

とりあえずCSVファイルが対象。
' 引数なし
If WScript.Arguments.Count = 0 Then WScript.Quit

Set objWS = CreateObject("WScript.Shell")
Set objFS = CreateObject("Scripting.FileSystemObject")

' 引数でループ
For i = 0 To WScript.Arguments.Count -1: Do
s = WScript.Arguments.Item(i)

If objFS.FileExists(s) Then
ProcFile(s)
Else
SearchFile(s)
End If
Loop Until 1: Next

r = objWS.PopUp("処理が終了しました。",3,"終了メッセージ",64)
'============================================================


' フォルダ内のファイル---------------------------------------
Sub SearchFile(DPath)
Set Folder = objFS.GetFolder(DPath)

' フォルダ内のフォルダ
For Each SubFolder In Folder.SubFolders: Do
SearchFile(SubFolder.Path)
Loop Until 1: Next

' フォルダ内のファイル
For Each File In Folder.Files: Do
ProcFile(File.Path)
Loop Until 1: Next
End Sub

' ファイル処理メイン ----------------------------------------
Function ProcFile(FPath)
ProcFile = False
If LCase(Right(FPath,3)) <> "csv" Then Exit Function
' ※※※処理実体を記述※※※

ProcFile = True
End Function
' ----------------------------------------------------------



[PR]
by yozda | 2012-04-30 13:53 | プログラミング | Trackback | Comments(7)
「同僚」たるもの、仲良しクラブになるな!
こんばんワイン。どーもボキです。

先ほどと同じで、プログラミングの話。
親子関係なら、上司と部下が理想といえる。では、互いが同等の立場だったらどうだろう?


その場合は、「同僚」になれ。


担当領域(機能)を分担し、それぞれが担当領域に特化する。
これが理想的な「同僚」関係だ。

自分の仕事(処理)に、同僚の成果(処理結果)が必要なら、
その成果だけをもらい、自分の仕事を進める。
決して、相手の仕事の進め方(処理ロジック)に介入してはいけない。

互いの成果(処理結果)を纏めての仕事が必要なら、その仕事(処理)は、上司(親)が取りまとめるべきだ。
どちらかの同僚にそれをさせてはならない。役割分担・上下関係が不明瞭になるからだ。

また同僚との関係は、決して仲良しクラブになってはいけない。先ほど同様に、互いに依存してはいけない。
そして、互いに雑用(共通の仕事)があるなら、それは派遣の方(共通処理ユニット)に集約する。

この形が理想。
なんか、仕事でも同じことがいえそうだね。


[PR]
by yozda | 2011-10-07 23:44 | プログラミング | Trackback | Comments(0)
親子の関係は「上司と部下」。「友達」には決してなるな!
こんばんワイン。どーもボキです。

親子の理想的な関係は、上司と部下の関係?それとも友達のような関係?


ボキの考えは、(理想的な関係を築いた)上司と部下だ。


よく友達(※)のような親子関係が理想というが、
それは、親が子の盾となりフィルタとなり余計なものを排除し、子供に遠慮などさせず伸び伸びと遊べるような環境を作ってやる。
だから子供にとっては友達のようにも感じられる親になっている。

こんな感じじゃないだろうか?

(※)本当は「友達」でなく「恋人」と書きたかったが、
   親子関係の話をするときにタイトルとして「恋人」ではあまりに違和感があるのでやめた。

上のような親子関係は、ここでの話での「友達」ではない。
むしろ、理想的な「上司と部下の関係」。


理想的な上司と部下の関係は、
仲が良いとはいえ、ある領域ではキッチリ線引きして距離を保つ。
上司は、部下の盾・フィルタとなり不要なものを排除し、
必要な情報、最低限の助言・指示を部下に与え、伸び伸びと仕事ができる環境を部下に提供する。
部下は、それを理解した上で、自分の領域を責任もってやりとげる。
上司は部下達からの成果を受け取り、それらをまとめた上でさらに上位の課題の達成を目指す。
互いを信頼し合い、互いの領域でのベストを尽くす。

こんな感じじゃなかろうか?


ここでの「友達」とは、
中学・高校の男子学生のように、しょっちゅう互いをチチくり合うような関係だ。

いくら仲が良いといっても、これは理想的な親子関係とはいえない。

親が子が同じレベルになっては意味がない。
子は親から何も吸収できないし、親はその経験を子の教育に活かせていない。

これまでの話は、前置きね。

-----------------------------------------------------------------------------------------------
プログラムも、この親子関係に注意しなければならない。
現実の親子関係と同様に、上司と部下のような関係を目指す必要がある。


親(呼び出す側)は、
盾となりフィルタとなり、子に情報を渡す前に、無用・不要なデータを排除する。

子(呼び出される側)は、
親から受け取った情報を処理する。子は子としての役割だけに専念する。
決して、親領域に介入してはいけないし、処理の途中に親の情報・援助も受けてはいけない。
(どうしても途中に親の情報・援助が必要なら、前もって渡せないか検討する)

親は、子から受け取った処理結果を使い、さらに上位の処理を行う。

これが理想の関係だ。


この理想的な関係を構築することができれば、
その子は完全に自立した存在となり、別の親の元でも同様の働きができる。


この関係が、『「友達」や「恋人」』のようになると、
開発・効率・メンテのすべて面で最悪のプログラムとなる。

親と子が色々なところでチチくり合い、互いの役割を分担できない。
子は自立できないから他に転用できない。親も同じ。共依存の共倒れだ。


今、修正しているプログラムがこれだ。もちろん俺がつくったものではない。

互いが依存の強すぎて、親子関係を修復できない。
恋人のようにチチくり合っているから始末に終えない。まるで近親相カンだ。


プログラムを書くときは、はじめに決めたポリシーは途中変えたらいけない。
途中ポリシーを変えるなら、ポリシーに反する箇所はすべて修正する覚悟が必要だ。
それがいやなら変えるな。

ポリシーがない奴は、近親相カンのようなプログラムしか書けない。
より良いプログラムを書きたいなら、上司と部下の関係を常に意識しろ。


[PR]
by yozda | 2011-10-07 22:48 | プログラミング | Trackback | Comments(2)
[VBScript] 右クリックメニュー > 送る で選択したファイルをバックアップする
こんばんワイン。どーもボキです。

プログラムやドキュメントを作成&編集する際、直前のバージョンを残したい時が多々ある。

Ctrl+ファイルのドラッグで、「コピー~ファイル名」のようにコピーファイルを残すのも手だ。
けど、ファイル名の「コピー~」が不細工。
マメにリネームする人ならとくもかく、ボキのようなズボラは、すぐに何のためのコピーなのかわからんなる。

なんで、VBScirpt と 右クリックメニュー > 送る を組み合わせて、
ファイルバックアップツールを作った。
導入方法
 1.以下のソースを、メモ帳にコピーする
 2.適当な名前をつけメモ帳を保存し、拡張子を「vbs」にする
 3.2のファイル自身(またはショートカット)を、
   C:\Documents and Settings\Administrator\SendTo に保存する
 以上。
'※バックアップ先フォルダを固定したい場合は、
' 以下のコメントを外し、適宜パスを編集すること
'cDPath_BackUp = "D:\BackUp\"

If WScript.Arguments.Count = 0 Then WScript.Quit

Set objWS = CreateObject("Wscript.Shell")
Set objFS = CreateObject("Scripting.FileSystemObject")

s = Now
b = Mid(s,13,1) = ":" ' 時間が一桁か判定、True/False=-1/0

ymd_hms = Mid(s,3,2) & Mid(s,6,2) & Mid(s,9,2) &"_" ' 月日が一桁の場合は、「0がつく」
h = Mid(s,12,2+b): If b Then h = "0" & h ' 時間が一桁の場合は、「0がつかない」
ymd_hms = ymd_hms & h & Mid(s,15+b,2) & Mid(s,18+b,2)

' backupフォルダを作成
dpth = cDPath_BackUp
' 指定フォルダがない場合は、ドロップされたパスにフォルダ作成
If dpth = "" Then dpth = objFS.GetParentFolderName(WScript.Arguments.Item(0)) &"\backup\"
If Not objFS.FolderExists(dpth) Then objFS.CreateFolder(dpth)

' 日付フォルダを作成
dpth = dpth & ymd_hms
cmnt = InputBox("
コメントつける?")
If cmnt <> "
" Then dpth = dpth &"_"& cmnt
dpth = dpth &"
\"
If Not objFS.FolderExists(dpth) Then objFS.CreateFolder(dpth)

' 選択ファイル・フォルダをコピー
For Each pth In WScript.Arguments :Do
If objFS.FolderExists(pth) Then
r = objFS.CopyFolder(pth, dpth)
Else
r = objFS.CopyFile(pth, dpth)
End If
Loop Until 1 :Next
利用イメージ
a0021757_2314076.gif
バックアップしたいファイルを選択し(複数もOK)、右クリックメニュー > 送る > バックアップvbs

a0021757_2313378.gif
必要なコメント入力 (フォルダ名となるので、禁止文字は入れられない。「\」とかね。)
a0021757_2313618.gif
年月日時分秒_任意コメントのフォルダが作成され、その中にコピーがとられる


[PR]
by yozda | 2011-09-19 23:06 | プログラミング | Trackback | Comments(0)
[VBScript] ラジオボタンダイアログを実現する その2
こんにチワワ。どーもボキです。

より改良したものはこちら

こん時のソース。IEをQuitしてなかったので、実行のたびにiexplore.exeが残ってしまってた。なので修正。

あとアイテムリストが指定数以上の場合は、プルダウンメニュー表示させる機能を追加した。
a0021757_1519732.gif
ラジオボックスで表示 (もともとの機能)


a0021757_151954.gif
上図は表示指定数=1とした場合。指定数=10とすると、画面上に10個は表示される。([∨]を押すと全項目が表示される)


それにしてもIEを使って実現しているから、実行は遅いよね。
すなおにInputBox使ったほうがストレスはないかもね。

以下、ソース。前回同様onclickのo(全角)は、o(半角)にして。
[PR]
by yozda | 2011-03-09 15:21 | プログラミング | Trackback(1) | Comments(0)
[Delphi] TFrameを上手に使ってメンテナンス性を向上させる 番外編 ~TFrameをDLLで使うコツ~
どーもボキです。

フレームを利用したウィンドウを持ったDLLでは、フレームを作成する際にエラーが発生してしまう。
それは、TFrameは、EXEのハンドル(Application.Handle)を親にして自身を作成しているから。

EXEプロジェクトの場合は、自身のEXEハンドルを親にしてフレームが作成される。
しかし、DLLの場合、Application.Handle = 0 となっている。
つまり、親とするハンドルがないため、フレーム作成時にエラーが発生してしまう。

このエラーは、DLLのメインとなるフォームに一文を追加することで簡単に回避できる。
これより、DLLを呼び出したEXEのハンドルを親にしてフレームが正常に作成される。
Application.Handle := FindWindow(nil, PChar(Application.Title));

参考サイト

[PR]
by yozda | 2011-02-12 23:36 | プログラミング | Trackback | Comments(0)
[Delphi] TFrameを上手に使ってメンテナンス性を向上させる 5 ~メインフォームの作成~
どーもボキです。

今回は、前回までに作成した子フレームを呼び出すメインフォームを作成する。

実装するコードは以下。
Create時のフレーム作成&Init呼び出し、ボタンクリックイベントでのProc呼び出しの
どちらもFR_Commonで処理しているのがわかるだろうか?(下線部)

メインフォーム(uFM_Main.pas)のソースコード
unit uFM_Main;

interface

uses
uFR_Common,
uFR_Test1,
uFR_Test2,
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, CheckLst;

type
TForm1 = class(TForm)
Pnl_Top: TPanel;
GBx_Left: TGroupBox;
Pnl_Main: TPanel;
LBx: TListBox;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure LBxClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
// ----------------------------------------------
procedure _initFrame(_FR : TFR_Common);
var
i : Integer;
begin
_FR.Parent := Pnl_Main; // フレームの親を指定
_FR.Align := alClient; //
i := LBx.Items.Add(_FR.Name); // フレーム名をリストに表示
LBx.Items.Objects[i] := _FR; // リストのObjectsにTFR_Commonのオブジェクトを格納
end;
// ----------------------------------------------
var
i : Integer;
begin
Pnl_Main.Align := alClient;
LBx.Align := alClient;

// FR_Testを作成
_initFrame(TFR_Test1.Create(Self));
_initFrame(TFR_Test2.Create(Self));

// Initを実行
for i := 0 to LBx.Count -1 do
TFR_Common(LBx.Items.Objects[i]).Init;

// FR_Test1を全面に表示
LBx.ItemIndex := 0;
TFR_Common(LBx.Items.Objects[0]).BringToFront;
end;



procedure TForm1.LBxClick(Sender: TObject);
var
i : Integer;
begin
i := LBx.ItemIndex;

// 該当するフレームを全面に表示
TFR_Common(LBx.Items.Objects[i]).BringToFront;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
i : Integer;
begin
i := LBx.ItemIndex;

// 該当するフレームのProcを実行
TFR_Common(LBx.Items.Objects[i]).Proc;
end;

end.
以下は、EXEの実行イメージ。
親フレームで処理させているにも関わらず、ちゃんと子フレームで実装した処理が実行されることが分かる。

これが、仮想メソッドをオーバーライドするってこと。
a0021757_22553231.gif
このようにTFrameを上手に利用すれば、
子フレームには、それぞれ独自処理をゴリゴリと実装でき、
それを呼び出すメインフォームでは、子フレームを意識することなく処理させることが出来る。

上手に活用して、無駄なくプログラムを管理してほしい。サンプルプログラム

[PR]
by yozda | 2011-02-12 23:16 | プログラミング | Trackback | Comments(0)
[Delphi] TFrameを上手に使ってメンテナンス性を向上させる 4 ~子フレームの作成2~
どーもボキです。

前回に引き続き、子フレームを作成する。
作成するフレームはこんな感じ。フレームにパネルを10枚貼り付けてある。
a0021757_22432049.gif


実装したコードは以下。
Initでは、パネルに表示されている文字を消去し、
Procでは、フレームにランダムに色を設定し、その色をベースにパネルの色をグラデーションさせている。

overrideを忘れずに。

この記事では、overrideのことよりも、むしろFindComponentでコンポーネントをfor文で管理したり、
指定した値分だけ色をズラす自作関数OffsetColorの方が、参考になるんじゃないかな?

子フレーム(uFR_Test2.pas)のソースコード
unit uFR_Test2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, uFR_Common, ExtCtrls;

type
TFR_Test2 = class(TFR_Common)
Panel1: TPanel;
Panel2: TPanel;
Panel3: TPanel;
Panel4: TPanel;
Panel5: TPanel;
Panel6: TPanel;
Panel7: TPanel;
Panel8: TPanel;
Panel9: TPanel;
Panel10: TPanel;
private
{ Private 宣言 }
public
{ Public 宣言 }
procedure Init; override;
procedure Proc; override;
end;

var
FR_Test2: TFR_Test2;

implementation

{$R *.dfm}

{ TFR_Common1 }



procedure TFR_Test2.Init;
var
i : Integer;
begin
inherited;

// パネルのCaptionを消す
for i := 1 to 10 do
TPanel(FindComponent('Panel' + IntToStr(i))).Caption := ''
end;



procedure TFR_Test2.Proc;
// TColorを指定したOffset分ずらす
function OffsetColor(iColor : TColor; Offset : Smallint) : TColor;
//----------------------------------------------------------------------------
function _offset(iByte : Byte) : Byte;
label _END_;
var
data : Smallint;
begin
data := iByte;
if (Offset > 0) and (data = $FF) then goto _END_;
if (Offset < 0) and (data = $00) then goto _END_;

Inc(data,Offset);

if data > $FF then data := $FF else
if data < $00 then data := $00;

_END_:Result := data;
end;
//----------------------------------------------------------------------------
var
cl : TColor;
cr,cg,cb : Word;
begin
// TColorをBGR毎に分ける
cl := iColor;

// B,G,R
cb := $FF and (cl shr 16); // Blue
cg := $FF and (cl shr 8 ); // Green
cr := $FF and cl; // Red

cb := _offset(cb);
cg := _offset(cg);
cr := _offset(cr);

Result := TColor((cb shl 16) or (cg shl 8) or cr);
end;
var
i : Integer;
c : TColor;
Pnl : TPanel;
begin
inherited;

// 色をグラデーション表示
Self.Color := Random($FFFFFF);
c := Self.Color;
for i := 1 to 10 do begin
Pnl := FindComponent('Panel'+IntToStr(i)) as TPanel;
Pnl.Color := OffsetColor(c,25);
c := Pnl.Color;
end;
end;

end.


[PR]
by yozda | 2011-02-12 22:50 | プログラミング | Trackback | Comments(0)
[Delphi] TFrameを上手に使ってメンテナンス性を向上させる 3 ~子フレームの作成1~
どーもボキです。

前回用意した親フレームを継承し、子フレームを作成する。
作成は、
ファイル > 新規作成 > その他、
表示されるウィンドウからプロジェクト名のタブを選択し、親フレーム(下図では、FR_Common)を選択する。
a0021757_16223072.gif


まずは、FR_Test1。
下図のように、フレームにラベルを貼り付けただけ。
a0021757_16255012.gif
実装したコードは以下。
Initでは、ラベルに「Init」という文字を表示し、Procでは、ラベルに現在の日時を表示させる。

このとき気をつけることは、メソッドの定義部にoverrideを付けること。
overrideを付けることで、親フレームで定義した仮想メソッドをオーバーライド(再宣言)できる。

inherited とは、親フレームの処理を実行させる命令文。
親フレームでは、処理の実体はなにも記述していないので、このinheritedでは何も行われない。削除してもかまわない。

子フレーム(uFR_Test1.pas)のソースコード
unit uFR_Test1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, uFR_Common, StdCtrls;

type
TFR_Test1 = class(TFR_Common)
Label1: TLabel;
private
{ Private 宣言 }
public
{ Public 宣言 }
procedure Init; override;
procedure Proc; override;
end;

var
FR_Test1: TFR_Test1;

implementation

{$R *.dfm}

procedure TFR_Test1.Init;
begin
Inherited;

Label1.Caption := Self.Name+'.Init';
end;

procedure TFR_Test1.Proc;
begin
inherited;

Label1.Caption := DateTimeToStr(Now);
end;

end.



[PR]
by yozda | 2011-02-12 16:25 | プログラミング | Trackback | Comments(0)
[Delphi] TFrameを上手に使ってメンテナンス性を向上させる 2 ~親フレームの作成~
どーもボキです。

前回の記事のつづき。

ひとつのフォームにすべての処理を実装するのではなく、
それぞれの機能毎にフレームを分ける というもの。

こうすることで、機能毎にソースコードのファイルが分かれるため、
機能毎の開発に集中できる。(もちろん、互いのソースが依存し合わないことが前提)

以下は、プログラムの実装・処理のイメージ。これから紹介する方法を使えば、
コードの管理も楽チン、開発の分担もしやすく、加えてメインフォームの実装自体もシンプルに仕上げることが出来る。
a0021757_1428832.gif



まずは、親となるフレームを用意する。親フレームの作成は、以下の画像のように
 ファイル > 新規作成 > フレーム で行う。
a0021757_14192172.gif


親フレームのソースは以下。コツは、
宣言したメソッドにvirtualをつけ、仮想メソッドにすること

それだけ。

親フレーム(uFR_Common.pas)のソースコード
unit uFR_Common;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;

type
TFR_Common = class(TFrame)
private
{ Private 宣言 }
TestNo : Integer;
public
{ Public 宣言 }

// 仮想メソッド(vertual)を定義する
procedure Init; virtual;

// 仮想メソッド(vertual)を定義する
procedure Proc; virtual;
end;

implementation

{$R *.dfm}

{ TFR_Common }

procedure TFR_Common.Init;
begin
// 処理本体を子フレームに実装するため、空でよい
end;

procedure TFR_Common.Proc;
begin
// 処理本体を子フレームに実装するため、空でよい
end;

end.


[PR]
by yozda | 2011-02-12 14:26 | プログラミング | Trackback | Comments(0)