TeraOmegaNetwork 2.0
<2010年2月>
31123456
78910111213
14151617181920
21222324252627
28123456
78910111213

Javaと比較(ジェネリックのパフォーマンス)
文字列の連結
T言語を更新
Windows7RC1でのT言語の動作について
複数のmainクラスを含めたjarファイルの実行メモ
テンプレート作成支援言語とは
VOクラス自動生成
ちょっとした事から自動生成
Excel VBA DB項目更新チェック
データベース共通アクセスクラステンプレート(Java)

プログラミング
・C#
・C/C++
・Java
・Visual Basic
・Visual Basic .NET
・色々な言語
・メモ
管理人の落書き
リンク
テンプレート作成支援言語






Web デベロッパー

必要科目
70-536
70-528
70-547



・Sun認定Javaプログラマー(SJC-P 035)
・OracleSilverFaeroe 9i
・UMTP Lv1
・基本情報技術者


・セキュリティスペシャリスト合格
・テンプレート作成支援言語(T言語)を広める事

  お勧め1「テンプレート作成支援言語(T言語)」ver 1.02         20010/01/18 更新
テンプレート作成支援言語について
ダウンロードする。

お勧め2「ブラウザ自動操作ツール(IEAuto2009)」ver 1.5.6   20010/01/18 新規登録
ブラウザ自動操作ツールについて・・・(作成中)
ダウンロードする。

質問や感想などについては、メール(ヘルプに記載)からお願いします。
要望については、おいおい検討して行きたいと思っています。注意:サボる可能性有り
専用の掲示板でも作ろうかな。そもそもこのHP、書く場所ないですね。


最近書き込んだ内容です。
主に、プログラミング関係の内容を書いています。
Internet Explorer 7 で表示確認してます。


00072  Javaと比較(ジェネリックのパフォーマンス)  登録日:2009/12/27 22:05:53  更新日:2009/12/27 22:13:01

サブカテゴリをJavaにしたら、C#との比較ですねw

ジェネリック情報をコンパイル後も保持するC#と保持しないJavaでパフォーマンスが
どれだけ違うのか計ってみました。
細かい内容は、『まじかんと』様のページにいろいろ載っています。
http://homepage2.nifty.com/magicant/programmingmemo/genericsjavavscs.html



C# Ver
  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
using System.Collections.Generic;

public class CsVer {
    private const int MAX = 1000000;
    
    public static void Main(string[] args) {

        List <string> lst  = new List <string>(MAX);
        List <string> lst2 = new List <string>(MAX);

        long start = System.Environment.TickCount;

        //溜め込む
        for (int i = 0; i < MAX; i++) {
            lst.Add("てすと");
        }

        //転記する
        foreach (string str in lst) {
            lst2.Add(str);
        }
        
        long stop = System.Environment.TickCount;
        System.Console.WriteLine("string偏 実行にかかった時間は " + (stop - start) + " ミリ秒です。");
        
        start = System.Environment.TickCount;

        List <int> lst3  = new List <int>(MAX);
        List <int> lst4  = new List <int>(MAX);

        //溜め込む
        for (int i = 0; i < MAX; i++) {
            lst3.Add(i);
        }

        //転記する
        foreach (int n in lst3) {
            lst4.Add(n);
        }
        
        stop = System.Environment.TickCount;
        System.Console.WriteLine("int偏 実行にかかった時間は " + (stop - start) + " ミリ秒です。");
    }
}


Java Ver
  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
import java.util.ArrayList;

public class JavaVer {
    private static final int MAX = 1000000;
    
    public static void main(String[] args) {

        ArrayList <String> lst  = new ArrayList <String>(MAX);
        ArrayList <String> lst2 = new ArrayList <String>(MAX);

        long start = System.currentTimeMillis();

        //溜め込む
        for (int i = 0; i < MAX; i++) {
            lst.add("てすと");
        }

        //転記する
        for (String str : lst) {
            lst2.add(str);
        }
        
        long stop = System.currentTimeMillis();
        System.out.println("String偏 実行にかかった時間は " + (stop - start) + " ミリ秒です。");

        start = System.currentTimeMillis();

        ArrayList <Integer> lst3 = new ArrayList <Integer>(MAX);
        ArrayList <Integer> lst4 = new ArrayList <Integer>(MAX);

        //溜め込む
        for (int i = 0; i < MAX; i++) {
            lst3.add(i);
        }

        //転記する
        for (int n : lst3) {
            lst4.add(n);
        }
        
        stop = System.currentTimeMillis();
        System.out.println("int偏 実行にかかった時間は " + (stop - start) + " ミリ秒です。");
    }
}


■実行結果
D:\Documents\Programing>java JavaVer
String偏 実行にかかった時間は 59 ミリ秒です。
int偏 実行にかかった時間は 353 ミリ秒です。


D:\Documents\Programing>CsVer
string偏 実行にかかった時間は 16 ミリ秒です。
int偏 実行にかかった時間は 31 ミリ秒です。


パフォーマンスを意識するため計測方法をどちらも同じ方法(時間を取得し計測)をとっています。
行っていることは、1000000回値をセットし、それを別のリストに1つずつコピーです。

参照型のStringは、そんなに変わらないのですが、値型のintに関しては、違いがでてきています。
Javaの方は、キャスト(Object型→Integer)後にアンボクシング(参照型→値型)を行う事で
パフォーマンスが悪くなっています。


計測環境
OS:Windows7
メモリ:3GB
CPU:Core2Quad 9450
.NetFramework 3.5 SP1
java version 1.6.0_17
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
続きを見る


00071  文字列の連結  登録日:2009/12/06 20:29:18  更新日:2009/12/06 20:29:18

Javaで仕事をしていると、StringBufferで文字列を連結しないと怒られたりするのですが、
実際問題、何でもかんでもStringBufferで文字列連結すると遅いんですよね。
パフォーマンス悪いからStringBuffer使えって言われているこのごろです。

たとえば、こんなプログラムとか。


StringBufferの使い方(悪い例)
  1
  2
  3
  4
StringBuffer sb = new StringBuffer();
sb.append("太郎:こんにちは、元気ですか?\n");
sb.append("次郎:はい。元気です。\n");
sb.append("太郎:わたしも元気です。\n");


上記のような場合は、そもそもプログラム実行中で文字列を連結する必要がないので、
素直にStringで足してあげたほうがいいのです。

Stringで定義するだけでいいのです。
  1
  2
  3
  4
String str = 
      "太郎:こんにちは、元気ですか?\n"
    + "次郎:はい。元気です。\n"
    + "太郎:わたしも元気です。\n";


このような書き方により、Javaのコンパイル段階で文字列が連結され、
プログラムを実行したときにはすでに連結された文字列が処理されるようになるのです。

他にも、複数回の文字列連結の代入を行わないかぎりはStringで十分だったりします。
逆に、知らずに、sb.append("aaa");を繰り返していると遅くなります。
なぜかと言うと
String str = 
      str1
    + str2
    + str3;
というように、プログラムを組んだ場合、Javaは最終的に以下のようなプログラムに
置き換えるからです。
StringBuffer sb = new StringBuffer()
    .append(str1)
    .append(str2)
    .append(str3);

StringBufferを使えばいいという考えだけで実装すると以下のようになってしまいます。
StringBuffer sb = new StringBuffer()
sb.append(str1);
sb.append(str2);
sb.append(str3);

毎回sbオブジェクトを介してアクセスするのでかえって遅くなってしまうのです。


結論。
StringBufferは、一度の文字列連結ですむ場合は使わない。
条件などにより足す足さないが異なるような場合に使えばいいかなと思います。
あと、ループ中に何度も連結される場合なども。

StringBufferを使う場合は、できるだけ、StringBuffer.append("")の戻り値で再度処理を行う。


最後に一言
仕事でプログラム組むときは、何だかんだ言ってもコーディング規約だけは守りましょうw
パフォーマンス ≒ コーディング規約
ロジックの書き方の統一 = コーディング規約
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
続きを見る


00070  T言語を更新  登録日:2009/11/19 8:17:03  更新日:2009/11/19 8:17:03

ひさびさの更新です。

・Case文を複数回使用すると、正しく処理されないのを修正。
・サンプル(JavaActionクラス(テンプレート))のビーンへの
 セッター、ゲッターの型がintになっていたのをBeanに修正。
・サンプルに(Caseバグ修正テスト(Ver1.01以降で確認))を追加。



00069  Windows7RC1でのT言語の動作について  登録日:2009/06/28 14:41:29  更新日:2009/06/28 14:41:29

無駄に長い話の前に、結論だけ言うと、
VirtualPCではなく普通に入れたWindows 7 RC1上では動作します。

★以下長い話
Windows 7 RC1環境で動くかどうか確かめるため、
VirtualPC 2007(以下、仮想環境)に、Windows 7 RC1をインストールし、その後、
開発環境Visual Studio 2010 Beta1をインストール。

いざ、実行してみると・・・
動かないw
2008で作っていても、中身は2005(.Net Framework 2.0)だし行けると思ったのに。
2008標準の(.Net Framework 3.5)じゃないのが実は仇!?といろいろ考えてしまった。

考えてもしょうがないので、
Visual Studio 2010 Beta1でデバッグしてみる事に。
すると、Clipboard.setTextでエラーになる。(何故!?)
ちなみに、仮想OSとしてではなく、実際のパソコンに直接インストールした
Windows 7 RC1、Visual Studio 2010 Beta1の環境だと動作する。

そもそも仮想環境のWindows 7 RC1だとClipboard.setTextが不安定っぽい。
ほぼ動かないです。やっかいな事にT言語が出すエラーメッセージが
「テンプレートファイルが正しくありません。」と出てきます。
ん〜〜、クリップボードへコピー失敗したときの例外考慮しないと駄目かな・・・
こんな所で落ちるとは思っていなかったですし。

仮想環境は対象外とし、Windows 7 RC1上では動作します。

仮想環境上のWindows 2000だと問題無いのに・・・
仮想環境上にWindows Vista入れたらどうなるのだろ??


追記
仮想環境にWindows 7 RC1だけ入れた状態でもClipboard.setTextでエラーになる。

エラー詳細
requested clipboard operation did not succeed.
要求されたクリップボード操作に成功しませんでした。
System.Runtime.InteropServices.ExternalException occurred
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
続きを見る


00068  複数のmainクラスを含めたjarファイルの実行メモ  登録日:2009/06/22 8:10:12  更新日:2009/06/22 8:12:11

複数のmainクラスを含めたjarファイルの実行メモ

D:\>javac S1.java

D:\>java S1
S1

D:\>javac S2.java

D:\>java S2
S2

D:\>jar cvf Sample.jar S1.class S2.class
マニフェストが追加されました。
S1.class を追加中です。(入 = 395) (出 = 273)(30% 収縮されました)
S2.class を追加中です。(入 = 395) (出 = 272)(31% 収縮されました)

D:\>java -classpath Sample.jar S1
S1

D:\>



00062  テンプレート作成支援言語とは  登録日:2009/05/24 14:02:09  更新日:2009/06/15 1:04:53

プログラミング支援ツール

ソフト名:テンプレート作成支援言語(T言語)

概要:複雑なプログラムを書かなくても、オリジナルのテンプレートを作成でき、
   開発の効率を何倍も高めることあできる。
      →ソースコードの自動生成が可能
   
背景:プログラムを作成するときに、自動的に生成されたら便利だな〜と思ったことは
   無いだろうか?例えば、単項目チェック時の処理。プロパティ(ゲッター、セッター)の作成、
   DBアクセス時の決まりきった処理の記述。JavaでStrutsを使っていればxmlの定義、
   など、決まりきった構文が数多く存在する。

   そこで思いつくのがエディタで、正規表現を駆使した置換でプログラムを自動生成したり、
   それぞれの自動生成用のプログラムを組んだりすることだろう。(私はそうしてきました)

   しかしプログラムや正規表現ではメンテナンスが大変。自動化するごとに作らなければいけない。
   そこで、自動化をさらに自動化できないだろうかと考えました。
   構文を定義すればそのままプログラムを出力できるような何かを・・・
   そこで生まれたのがテンプレートの作成が簡単にできてしまう言語、
   テンプレート作成支援言語(T言語)です。以下T言語と呼ぶ

使用用途
   ・エラーチェックの仕様書には、必須チェック、数値チェック、英字チェックなど
    画面の項目に対してどのようなチェックを行うのか定義されている。
    そして、その定義を元にプログラムを書くときに、T言語を使用する。
    項目チェックが多ければ多いほどT言語の効力を発揮!

   ・Struts2フレームワークでプログラムを組むとき、
    画面名、画面ID、遷移先画面名、遷移先画面ID、アクション名などを定義したファイルを
    元に、アクションクラスの作成、xmlの定義など、スケルトンの作成にも使用できる。

   ・テーブルレイアウト(列の項目定義)仕様書を元に、エンティティクラス(VOクラス、
    列の項目を全てもったVOクラス)を作成できる。画面項目定義書があれば、FormBean
    が作成できる。・・・プロパティ(ゲッター、セッター)の集まりのクラスの作成

    などなど。他にも色々あります。(サンプルなど載せて行こうと思ってます)


   ※注意
    仕様書に定義してある項目をCSV(タブ区切りでも可能)で定義したファイルにしておくという
    前作業はありますが(先に言えとか言わないでくださいw)
    間違いなく効果はあると思っています。



〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
続きを見る


00067  VOクラス自動生成  登録日:2009/06/15 0:22:49  更新日:2009/06/15 0:22:49

JavaでWebアプリを作っていると、必ずと言っていいほど出てくるクラスが
VOクラス(Beanクラス、Domainクラス)と呼ばれているアクセッサークラス(ゲッター、セッター)
クラスです。このクラスも項目定義からおこせたら便利ですよね。

元となる項目一覧は、テーブル設計書や画面項目定義書などいろいろあるとは思いますが、
VOクラスの自動生成サンプルを公開します。

CSVファイルには、以下の項目を定義

CSVデータ
  1
  2
  3
  4
クラス名,変数名,型,日本語名称
SampleVO,id,int,ナンバー
SampleVO,name,String,名前
SampleVO,old,int,年齢



VOクラステンプレートサンプル
  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
import java.io.Serializable;

/**
 * %クラス名%.#One#
 */
class %クラス名%.#One# implements Serializable {
    /** シリアルID */
    private static final long serialVersionUID = 1L; 

    /** コンストラクタ */
    public %クラス名%.#One#() {
    }

%START%
    /** %日本語名称% */
    private %型% %変数名%;
%END%


%START%
    /**
     * %日本語名称%を取得します。
     * 
     * @return %変数名% %日本語名称%
     */
    public %型% get%変数名%.#InitUpper#() {
        return %変数名%;
    }

%END%
%START%
    /**
     * %日本語名称%をセットします。
     * 
     * @param %変数名% %日本語名称%
     */
    public void set%変数名%.#InitUpper#(%型% %変数名%) {
        this.%変数名% = %変数名%;
    }

%END%
}



実行結果
  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
import java.io.Serializable;

/**
 * SampleVO
 */
class SampleVO implements Serializable {
        /** シリアルID */
        private static final long serialVersionUID = 1L; 

    /** コンストラクタ */
    public SampleVO() {
    }

    /** ナンバー */
    private int id;
    /** 名前 */
    private String name;
    /** 年齢 */
    private int old;


    /**
     * ナンバーを取得します。
     * 
     * @return id ナンバー
     */
    public int getId() {
        return id;
    }

    /**
     * 名前を取得します。
     * 
     * @return name 名前
     */
    public String getName() {
        return name;
    }

    /**
     * 年齢を取得します。
     * 
     * @return old 年齢
     */
    public int getOld() {
        return old;
    }

    /**
     * ナンバーをセットします。
     * 
     * @param id ナンバー
     */
    public void setId(int id) {
        this.id = id;
    }

    /**
     * 名前をセットします。
     * 
     * @param name 名前
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 年齢をセットします。
     * 
     * @param old 年齢
     */
    public void setOld(int old) {
        this.old = old;
    }

}



Eclipseからも自動生成することはできますがコメントに、フィールド上で使用した日本語の
コメントをセットすることは、できなかったと思います。ゲッターセッターのコメントを吐き出しても
結局最後は自分で編集した記憶があります。(※私の知る限りでは・・・)
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
続きを見る


00066  ちょっとした事から自動生成  登録日:2009/06/04 0:44:31  更新日:2009/06/04 1:43:51

ソースの自動生成と言うと、設計書(定義ファイルも含む)と自動生成ツールを
使って、ある程度のの決まりきった処理を自動で出力してくれる。
ただ、そういうツールでは、細かい所までは、自動生成してくれない。

例えば・・・

画面に入力項目が10個ありました。
そして、その画面はDBから取得した値をデフォルト値とします。(更新モード)
それらの項目は、1つでも変更を行っていないと
DBへ更新を行ってはいけません。
なお、この考えは、他の画面でも同様とします。

ここで、変更前と変更後の2つの値の比較について考えてみる。
プログラムは以下のようになる。

if(変更前項目1.equals(変更後項目1)) { return false; }
if(変更前項目2.equals(変更後項目2)) { return false; }
if(変更前項目3.equals(変更後項目3)) { return false; }
if(変更前項目4.equals(変更後項目4)) { return false; }
if(変更前項目5.equals(変更後項目5)) { return false; }
                 以下略(面倒くさくなりましたw)

このように同じような事が何度も出てくる。
面倒ですね。しかも似たような項目があった場合など、タイプミスする場合も考えられますね。
タイプミスを踏まえ、ソースのチェックもしないといけないです。

そこで、こういうちょっとしたプログラムからでも自動生成できないか考える。

・項目は10個ある。
・if(変更前★値★.equals(変更後★値★)) { return false; }
   ★値★の箇所以外全部ロジックは同じ


テンプレート作成支援言語(T言語)の出番です。

本来ですと項目定義ファイルと、テンプレートファイルの2つのファイルを
用意するが、1つにまとめてでもできるので1つにまとめる。


〇ファイル名:比較テンプレート.txt (値入り(1行目〜11行目))
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
項目名称
項目1
項目2
項目3
項目4
項目5
項目6
項目7
項目8
項目9
項目10

if(変更前%項目名称%.equals(変更後%項目名称%)) { return false; }




〇実行結果:比較テンプレート(値(1行目〜11行目)も出力されている気にしない)
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
項目名称
項目1
項目2
項目3
項目4
項目5
項目6
項目7
項目8
項目9
項目10

if(変更前項目1.equals(変更後項目1)) { return false; }
if(変更前項目2.equals(変更後項目2)) { return false; }
if(変更前項目3.equals(変更後項目3)) { return false; }
if(変更前項目4.equals(変更後項目4)) { return false; }
if(変更前項目5.equals(変更後項目5)) { return false; }
if(変更前項目6.equals(変更後項目6)) { return false; }
if(変更前項目7.equals(変更後項目7)) { return false; }
if(変更前項目8.equals(変更後項目8)) { return false; }
if(変更前項目9.equals(変更後項目9)) { return false; }
if(変更前項目10.equals(変更後項目10)) { return false; }


単純な置き換え処理だが、これも自動生成と言える。
今回のような自動生成だと、テンプレートに定義したロジックと
実際出力するロジックが、ほぼ同じだと言う事も特徴。
これをもっと発展させていくとゲッター、セッター(Bean、VOクラス)を
テンプレートから起こせたり、DBアクセス層を作ったりと、さまざまな
ロジックを自動生成できる。

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
続きを見る


00063  Excel VBA DB項目更新チェック  登録日:2009/05/26 1:40:07  更新日:2009/06/01 1:00:46

会社のセキュリティ上、ソフトがダウンロードできない状況でもテキスト(ここに書いてある
マクロを見ることはできますからねw)と言うわけでちょっとマクロをコピペしてみました。
本当は、SQL接続部分とかあるのですが、落書きが大きくなるので省略。

内容は、データベースの更新前、更新後を比較したいときに使うマクロです。(2つの表の差分を求める)
実際に実装してみると、比較シートの方に、削除、登録、更新が人目で分かるように表示されます。
前提条件として、プライマリキーで、更新前、更新後の明細はソート(昇順)しておくこと。
ヘッダー部分には、アンダーバーを引いておく。(ルール無視すると無限ループ発生します!)
使う場合は、このマクロをコピーして適当に編集してください。もしかすると何か関数がもれてる
かもしれないです。その変は臨機応変と言うことで。責任取れません。

更新前のシートと更新後のシートと、さらに比較するようのシートを3つ用意する。

そして、以下のマクロを定義する。

★比較シートに記述
Option Explicit

Dim Before As Worksheet  '更新後シート
Dim After As Worksheet   '更新前シート
Dim Cmp As Worksheet     '比較用シート

Dim PkeyCol As Integer   'プライマリキーの最終列位置(例:主キーが3つあった場合は3になる)

Const START_COL As Integer = 2      '比較開始行
Const ATTRIBUTE_COL As Integer = 1  '属性行

'エントリーポイント
'更新前と更新後で比較を行う。
Private Sub CmdBeforeAfterCmp_Click()
On Error GoTo Exception

    Call SetOffscreenStart

    Set Before = Sheets("更新前")
    Set After = Sheets("更新後")
    Set Cmp = Sheets("比較")
    
    'クリア
    Call Clear
   
    '何列目まで主キーか求める。
    PkeyCol = GetPkeyCol()
    If PkeyCol = -1 Then
        Cmp.Range("A1").Select
        Call SetOffscreenStop
        
        Exit Sub
    End If
    
    Dim BeforePKey As String
    Dim AfterPKey As String
    Dim BeforeRowIdx As Integer
    Dim AfterRowIdx As Integer
    Dim CmpRowIdx As Integer
    
    BeforeRowIdx = 4
    AfterRowIdx = 4
    CmpRowIdx = 4
    
    BeforePKey = MakePKey(Before, BeforeRowIdx) '更新前主キーを;で連結する
    AfterPKey = MakePKey(After, AfterRowIdx) '更新後主キーを;で連結する
    
    Call CopyPasteRow(Before, 3, Cmp, 3)
    
    'オートフィルタをセットする。
    Cmp.Range("A3").Select
    Selection.AutoFilter

    '行ループ
    Do While True
        '終了条件
        If Before.Cells(BeforeRowIdx, START_COL) = "" And _
                After.Cells(AfterRowIdx, START_COL) = "" Then
            Exit Do
        End If

        If Before.Cells(BeforeRowIdx, START_COL) = "" Then
            '更新前のレコードを最後まで読み終えた場合(更新後のレコードが更新前に存在しない場合(追加された場合))
            
            Call CopyPasteRow(After, AfterRowIdx, Cmp, CmpRowIdx) '更新後のレコードをセットする
            
            Selection.Interior.ColorIndex = 38 'ピンクにする
            Cmp.Cells(CmpRowIdx, ATTRIBUTE_COL) = "INS"
            
            AfterRowIdx = AfterRowIdx + 1 '更新後シートの行を進める
            AfterPKey = MakePKey(After, AfterRowIdx) '更新後主キーを;で連結する
            
        ElseIf After.Cells(AfterRowIdx, START_COL) = "" Then
             '更新後のレコードを最後まで読み終えた場合(更新前のレコードが更新後に存在しない場合(削除された場合))
            
            Call CopyPasteRow(Before, BeforeRowIdx, Cmp, CmpRowIdx) '更新前のレコードをセットする
            
            Selection.Interior.ColorIndex = 15 '灰色にする
            Cmp.Cells(CmpRowIdx, ATTRIBUTE_COL) = "DEL"
            
            BeforeRowIdx = BeforeRowIdx + 1 '更新前シートの行を進める
            BeforePKey = MakePKey(Before, BeforeRowIdx) '更新前主キーを;で連結する
            
        Else
            If BeforePKey < AfterPKey Then
                 '更新前のレコードが更新後に存在しない場合(削除された場合)
                
                Call CopyPasteRow(Before, BeforeRowIdx, Cmp, CmpRowIdx) '更新前のレコードをセットする
                
                Selection.Interior.ColorIndex = 15 '灰色にする
                Cmp.Cells(CmpRowIdx, ATTRIBUTE_COL) = "DEL"
                
                BeforeRowIdx = BeforeRowIdx + 1 '更新前シートの行を進める
                BeforePKey = MakePKey(Before, BeforeRowIdx) '更新前主キーを;で連結する
                
            ElseIf BeforePKey > AfterPKey Then
                '更新後のレコードが更新前に存在しない場合(追加された場合)
                
                Call CopyPasteRow(After, AfterRowIdx, Cmp, CmpRowIdx) '更新後のレコードをセットする
                
                Selection.Interior.ColorIndex = 38 'ピンクにする
                Cmp.Cells(CmpRowIdx, ATTRIBUTE_COL) = "INS"
                
                AfterRowIdx = AfterRowIdx + 1 '更新後シートの行を進める
                AfterPKey = MakePKey(After, AfterRowIdx) '更新後主キーを;で連結する
                
            Else
                '一致する場合
                
                Call CopyPasteRow(After, AfterRowIdx, Cmp, CmpRowIdx) '更新後のレコードをセットする
                
                Dim ColIdx As Integer
                ColIdx = START_COL
                
                '列に対するループ、値が更新されているかチェックしていく
                Do While True
                    '終了条件
                    If Before.Cells(3, ColIdx) = "" Then
                        Exit Do
                    End If
                    
                    '一致しない場合(更新されている場合)
                    If Before.Cells(BeforeRowIdx, ColIdx) <> Cmp.Cells(CmpRowIdx, ColIdx) Then
                        Cmp.Cells(CmpRowIdx, ColIdx).Select
                        Selection.Interior.ColorIndex = 36 '黄色にする
                        
                        Cmp.Cells(CmpRowIdx, ATTRIBUTE_COL) = "UPD"
                        
                        Call CsllsAddComment(CmpRowIdx, ColIdx, _
                            Before.Cells(BeforeRowIdx, ColIdx), Cmp.Cells(CmpRowIdx, ColIdx), _
                            AfterPKey)
                    End If
                    
                    ColIdx = ColIdx + 1
                    
                Loop '列ループ
                
                BeforeRowIdx = BeforeRowIdx + 1 '更新前シートの行を進める
                BeforePKey = MakePKey(Before, BeforeRowIdx) '更新前主キーを;で連結する
                
                AfterRowIdx = AfterRowIdx + 1 '更新後シートの行を進める
                AfterPKey = MakePKey(After, AfterRowIdx) '更新後主キーを;で連結する
            End If
        End If
        
        CmpRowIdx = CmpRowIdx + 1 '比較シートの行を進める
        
    Loop '行ループ

    Call SetOffscreenStop
    
    Exit Sub
    
'例外処理
Exception:
    MsgBox "エラー内容:" & Err.Description, vbOKOnly, "異常終了"
    
    Call SetOffscreenStop

End Sub

'比較シートをクリアする
Private Sub Clear()
    Cmp.Cells.Select
    Range("C29").Activate
    Selection.ClearContents
    Selection.Interior.ColorIndex = xlNone
    
    Call CellsClearComments
End Sub

'セルにコメントを付加する。
Private Sub CsllsAddComment(ByVal row As Integer, ByVal col As Integer, ByVal updBefore As String, ByVal updAfter As String, ByVal priKey As String)
    Cmp.Cells(row, col).AddComment
    Cmp.Cells(row, col).Comment.Text Text:="主キー:" & priKey & Chr(10) & "変更前:" & updBefore & Chr(10) & "変更後:" & updAfter
    
    Cmp.Cells(row, col).Comment.Visible = True  'Shapeを変更したいためtrueにする。
    Cmp.Cells(row, col).Select                  'セルを選択する
    Selection.Comment.Shape.Select True         'コメントを選択する 『=』はいらない
    Selection.AutoSize = True                   'AutoSizeを有効にする
    Selection.ShapeRange.IncrementLeft -100
    Cmp.Cells(row, col).Comment.Visible = False '非表示にする。
    
End Sub

'セル上すべてのコメントをクリアする。
Private Sub CellsClearComments()
    Cmp.Cells.Select
    Selection.ClearComments
    Cmp.Cells(1, 1).Select
End Sub

'更新前シートから、何列目まで主キーか求める。
Private Function GetPkeyCol() As Integer
    Dim PkeyCol As Integer
    
    Dim i As Integer
    For i = START_COL To 255
        '終了条件
        If Before.Cells(3, i) = "" Then
            Exit For
        End If
        
        '終了条件(下線では無い場合)
        If Before.Cells(3, i).Font.Underline <> xlUnderlineStyleSingle Then
            Exit For
        End If
    Next
    
    '主キーが設定されていない場合はエラー
    If i = START_COL Then
        MsgBox "主キーの列名の書式を下線にしてください。", vbOKOnly, "エラー"
        i = 0
    End If
    
    PkeyCol = i - 1 '主キー列
    
    GetPkeyCol = PkeyCol
End Function


'プライマリーキーを;で連結して返す
Private Function MakePKey(ByRef sheet As Worksheet, ByVal rowIdx As Integer) As String
    Dim wkStr As String
    wkStr = ""
    
    Dim i As Integer
    For i = START_COL To PkeyCol
        wkStr = wkStr & sheet.Cells(rowIdx, i) & ";"
    Next
    
    MakePKey = wkStr

End Function


'第1引数で指定したコピー元のワークシートの行を
'第3引数で指定したコピー先のワークシートの行にコピーする。
Private Sub CopyPasteRow( _
        ByRef Sheet1 As Worksheet, ByVal rowIdx1 As Integer, _
        ByRef Sheet2 As Worksheet, ByVal rowIdx2 As Integer)
       
    Sheet1.Select
    Sheet1.Rows(rowIdx1 & ":" & rowIdx1).Select
    Selection.Copy
    Sheet2.Select
    Sheet2.Rows(rowIdx2 & ":" & rowIdx2).Select
    ActiveSheet.Paste
End Sub



★モジュールファイルに記述
Option Explicit

''' 
'''再計算および再描画を無効にする
''' 
Public Sub SetOffscreenStart()
    Application.Cursor = xlWait
    Application.StatusBar = "処理中..."
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
End Sub


''' 
'''再計算および再描画の無効を止める
''' 
Public Sub SetOffscreenStop()
    Application.Cursor = xlDefault
    Application.StatusBar = ""
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
End Sub




実装時のシートの状態
A列は、空けておく。
3行目はヘッダー
4行目から明細

ブックの構成
    シートは3つ用意する
    ★更新前シート
    ★更新後シート
    ★比較シート
    
    モジュールを1つ
    ★モジュールファイル
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
続きを見る


00065  データベース共通アクセスクラステンプレート(Java)  登録日:2009/06/01 0:42:23  更新日:2009/06/01 0:42:57

T言語サンプルです。
データベース共通アクセスクラスを利用したクラスを出力するためのテンプレートです。
JavaDocは、中途半端ですが、とりあえず、アップします。

CSVファイルは、以下のように定義してあります。
テーブル名    列名    DB型    Java型    コメント
table1    nmid    INTEGER    Integer    ID
table1    vcname    VARCHAR    String    名前
table1    nmold    INTEGER    Integer    年齢


テンプレートとは直接関係ないですが、テスト時のテーブル構造
データベースは、SQL Server 2005
テーブル:table1
列:nmid    int  PrimaryKey
    vcname  nvarchar(50)
    nmold       int
    dtupd       char(14)
    dtins   char(14)




データベース共通アクセスクラス、テンプレート(Java)
  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
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
//各種業務Daoクラス★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

/**
 * <pre>
 * Dao
 * %テーブル名%.#One#.#InitUpper#テーブル
 * </pre>
 */
class %テーブル名%.#One#.#InitUpper#Dao extends BusinessCommonDao  {
    public %テーブル名%.#One#.#InitUpper#Dao(Connection con) throws SQLException {
        super(con);
    }

    public ArrayList<%テーブル名%.#One#.#InitUpper#> getAll(%テーブル名%.#One#.#InitUpper# tbl)
            throws SQLException {
        final String SQL_GETALL = 
             "  SELECT "
           + super.getCommonColumnsNameBySelect() //共通項目(更新日付、更新者名など)
           + "         ,%列名%.#Upper# "
           + "    FROM "
           + "         %テーブル名%.#One#.#Upper# ";
        //TODO: ★tblの値を元に検索条件を指定★

        setSql(SQL_GETALL);

        return executeQuery(%テーブル名%.#One#.#InitUpper#.class);
    }

    public int insert(%テーブル名%.#One#.#InitUpper# tbl) throws SQLException {
        final String SQL_INSERT = 
             "  INSERT INTO %テーブル名%.#One#.#Upper#( "
           + super.getCommonColumnsNameByInsert()
           + "         ,%列名%.#Upper# "
           + "      ) VALUES( "
           + super.getCommonPlaceholderByInsert()
           + "         ,? " //%列名%.#Upper#  %コメント%
           + "      )";
        
        setSql(SQL_INSERT);
        
        super.setCommonObject(tbl);
        addObject(tbl.get%列名%.#InitUpper#(), Types.%DB型%);
        
        return executeUpdate();
    }
}


/**
 * <pre>
 * Domain
 * %テーブル名%.#One#.#InitUpper#テーブル
 * </pre>
 */
class %テーブル名%.#One#.#InitUpper# extends BaseDomain {
    private %Java型% %列名%;

%START%
    public %Java型% get%列名%.#InitUpper#() {
        return this.%列名%;
    }

    public void set%列名%.#InitUpper#(%Java型%  %列名%) {
        this.%列名% = %列名%;
    }
%END%

    public String toString() {
        return super.toString() //共通項目(更新日付、更新者名など)
               + "," + %列名%
            ;
    }
}

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
続きを見る