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 |
Sub test() 'Accessにあるクエリを作成するプロシージャを呼ぶ 'クエリを作ってあるmdbなら不要 Set a = CreateObject("Access.Application") With a .OpenCurrentDatabase "xxx.mdb" .Visible = False .Application.Run "xxx" .Quit End With Set a = Nothing 'ここからはADO Set c = CreateObject("ADODB.Connection") Set r = CreateObject("ADODB.Recordset") c.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=xxx.mdb;" r.Open "test", c 'クエリで動的なテーブルを開く。 'ちゃんとSQL Serverまで読みにいっている。Accessの中にキャッシュなどしていないよう ActiveSheet.Cells(1, 1).CopyFromRecordset r End Sub |
C# Access(accdb) 比較
業者製作のAccessファイル+クライアントで、クライアントプログラム側で操作した結果が
Access内部でどう変更されるか調べようと思ったがAccessファイルが大きすぎた。
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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; /* Microsoft Access データベース エンジン 2010 再頒布可能コンポーネント (AccessDatabaseEngine.exe) ファイルがaccdb、ACE.OLEDB.12.0を利用する場合、 PCが32bitならインストールしないとプロバイダが見つからない。*/ namespace データベース差分チェック { public partial class Form1 : Form { UserDataSet uds1 = null; UserDataSet uds2 = null; public Form1() { InitializeComponent(); comboBox1.Enabled = false; comboBox2.Enabled = false; comboBox1.SelectedIndexChanged += new EventHandler(ComboxChange1); comboBox2.SelectedIndexChanged += new EventHandler(ComboxChange2); } private void ComboxChange1(object sender, EventArgs e) { if (uds1 == null) return; dataGridView1.DataSource = uds1.AccessDataSet.Tables[comboBox1.Text]; } private void ComboxChange2(object sender, EventArgs e) { if (uds2 == null) return; dataGridView2.DataSource = uds2.AccessDataSet.Tables[comboBox2.Text]; } private void button1_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); if (ofd.ShowDialog() == DialogResult.OK) { if (listBox1.Items.Count <= 1) { listBox1.Items.Add(ofd.FileName); } else { listBox1.Items[0] = listBox1.Items[1]; listBox1.Items.RemoveAt(1); listBox1.Items.Add(ofd.FileName); } } } private void button2_Click(object sender, EventArgs e) { comboBox1.Items.Clear(); comboBox2.Items.Clear(); if (listBox1.Items.Count == 1) { this.uds1 = new UserDataSet(listBox1.Items[0].ToString()); for (int i = 0; i < uds1.AccessDataSet.Tables.Count; i++) { comboBox1.Items.Add(uds1.AccessDataSet.Tables[i].TableName); } comboBox1.Enabled = true; } if (listBox1.Items.Count == 2) { this.uds2 = new UserDataSet(listBox1.Items[1].ToString()); for (int i = 0; i < uds2.AccessDataSet.Tables.Count; i++) { comboBox2.Items.Add(uds2.AccessDataSet.Tables[i].TableName); } comboBox2.Enabled = true; } } } public class UserDataSet { public DataSet AccessDataSet = new DataSet(); public UserDataSet(string filePath) { using (System.Data.OleDb.OleDbConnection con = new System.Data.OleDb.OleDbConnection( @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";JET OLEDB:Database Password=xxx")) { try { con.Open(); //fillの場合不要だがGetSchemaで必要。 DataTable dt = con.GetSchema("Tables"); foreach (DataRow r in dt.Rows) { string tableName = r["TABLE_NAME"].ToString(); //System.Diagnostics.Debug.Print(r["TABLE_NAME"].ToString()); if (tableName.Substring(0, 4) != "MSys") { using (System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter()) { System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand("select * from " + tableName, con); da.SelectCommand = cmd; DataTable newTable = new DataTable(tableName); AccessDataSet.Tables.Add(newTable); da.Fill(AccessDataSet.Tables[tableName]); } } } } catch(Exception e) { MessageBox.Show(e.Message); return; } finally { con.Close(); } } } } } |
C# 設計メモ
順不同。思いつたら更新。
・クラスの単位
GUIのフォーム単位のクラスが基本(GUIがなければユースケース管理)で、その中で必要に応じてクラスに抜き出す。
1.変更の発生しそうな部分をクラスに抜き出す。
拡張ポイント(DI)
2.共通で使う部分をクラスに抜き出す。
アダプター(合成+委譲)で共通化
ストラテジー
3.他クラスから参照される部分をクラスに抜き出す。
4.テストしたい部分をクラスに抜き出す。
5.インスタンス生成をクラスに抜き出す。
生成処理を1箇所にまとめることで変更に対応しやすく。
DIが連続して上位レイヤーに引数が溢れてきたら。
(作ると使うを分ける)
6.プリミティブな値に型定義する場合。
値オブジェクト
・クラス、インターフェース、メソッド
参照と変更を分ける(CQS)。意味のある名前にする。スコープが大きいのに一文字変数名や、ハードコーディングしている数値など避ける。とりあえずメソッドは小さく。
・レイヤー
適切にクラス分けしていけば最終的に自然とレイヤーに当てはまる形になっているのでそれほど意識しない。
・依存関係のコントロール
クラス間の依存をインターフェースへの依存にすること。派生クラスの追加で対応する。拡張ポイントと呼ぶ場合もある。
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 |
public partial class Form1 : Form { public Form1() { InitializeComponent(); // 下位レイヤーに依存すると下位レイヤーの変更に影響を受ける new App(""); // AppでSayHelloのインスタンス生成をしている new App(); // SayHelloのインスタンスをBuilderで生成し、App内で利用している // (生成と利用の分離) new App(new Builder()); // Builderの生成をAppの生成と同じレイヤー化 // AppはBuilderに依存(利用)していたが、 // App、BuilderともにIFactoryに依存することになる // (DI) } } class App { public App(string dummy) { new SayHello().Do(); } public App() { new Builder().CreateObj().Do(); } public App(IFactory f) { f.CreateObj().Do(); } } class Builder : IFactory { public SayHello CreateObj() { return new SayHello(); } } interface IFactory { SayHello CreateObj(); } class SayHello { public void Do() { MessageBox.Show("hello"); } } |
・DB系
DBの依存関係。FKがある方が依存している。依存している方が子。PKは重複できないけど、FKは重複できるので、FKある方が多。
複合主キーとなっている関係従属を取り除く正規化は当たり前に発生するので、正しいモデリングをすると必然的に複合主キーが現れる。サロゲートキーを入れる場合、制約はアプリ側で対応する。例えば仕入価格を、仕入先・商品・開始年月で識別するような場合。
参照整合性。実務では完全な制約が必要ではなく、緩い制約の方が都合がいいときもある。ただし、構造が壊れやすくはなるので注意。
SQL DB正規化
直ぐ忘れてしまう。
先ず、一方の値が決まると他方も決まるものを、関数従属性という。
第一正規化
一つのセルに複数のデータを持たない。
第二正規化
部分関数従属を取り除く。
部分関数従属とは、主キーの一部だけで一意に決まる列のこと。
主キーが複数あり、その内の一つだけで値が決まるものを別のテーブルにする。
第三正規化
推移的関数従属を取り除く。
推移的関数従属とは、テーブル内の段階的な関数従属のこと。
つまり、主キー以外と関数従属があること。
主キー以外の項目で、他の列の値を一意に決めるものを別テーブルにする。
例えば、(主)社員ID → 部署コード → 部署名
部署コードが決まれば部署名が決まる。当然主である社員IDと部署コードは関数従属の関係なので、
段階的な関数従属があるといえる。
部分関数従属、推移的関数従属を取り除くことの必要性。
あるテーブルの中で推移的関数従属が残っていると、間違った登録が可能。(会社コードと会社名)
また、主キーが不明の段階で登録できない。
キー| メンバー名 | 会社コード | 会社名
1 | 太郎 | 0000 | AAA
2 | 次郎 | 0001 | AAA
テーブルの関連
1対1、1対多、多対多があるが、通常1対多のみ使う。
多対多となる場合、関連実体というテーブルを作る。ただ、通常の業務要件では、
マスタとマスタを直接関連付けることはないので、普通に考えると多対多とはならない。
Ubuntu Java Tomcatインストール
インストール
sudo apt-get install defaut-jdk
java -version
今回は、1.8.0_121
sudo apt-get install tomcat7
sudo update-alternatives –list java
でJavaのパスを確認。
今回は、
/usr/lib/jvm/java-8-openjdk-i386/jre/bin/java
と表示される。
~/.profile
に以下を追記する。
JAVA_HOME=”/usr/lib/jvm/java-8-openjdk-i386/jre/bin/java”
PATH=”$JAVA_HOME/bin:$PATH”
CATALINA_HOME=”/usr/share/tomcat7″
profileの記述で違う方法として、
/etc/profile.d/java.sh
を作成し、
JAVA_HOME=”/usr/lib/jvm/java-8-openjdk-i386/jre/bin/java”
と追記し、
source ./java.sh
を実行する方法もある。今回はやらない。
ここで再起動。
echo $JAVA_HOME
で確認すると、
/usr/lib/jvm/java-8-openjdk-i386/jre/bin/java
と表示される。
ファイアーウォールの設定
sudo ufw allow 8080/tcp
ここまで来たら、
sudo /etc/init.d/tomcat7 restart
を実行。
http://192.168.102.15:8080/
にアクセス。
その他
設定ファイルの場所
sudo vim /etc/tomcat7/server.xml
Tomcatの状況確認
sudo /etc/init.d/tomcat7 status
もしeclipseでTomcatを操作する場合
http://www.eclipsetotale.com/tomcatPlugin.html#A3
から
tomcatPluginV331.zip
を保存し解凍して、
C:\eclipse\plugins
の中へ
C# Interpreter
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 77 78 79 80 81 82 83 84 |
namespace ConsoleApplication2 { /* Interpreter 規則のあるフォーマットを解析し処理する。 */ public interface Operand { //処理対象を表す文字列を返す string GetOperandString(); } //処理対象クラス public class Ingredient : Operand { //処理対象を表す文字列 private string OperandString = ""; public Ingredient(string operandString) { this.OperandString = operandString; } //処理対象を表す文字列を返す。 public string GetOperandString() { return this.OperandString; } } //処理結果クラス public class Expression : Operand { private Operator operate = null; //処理内容を表すOperatorを引数にとる public Expression(Operator operate) { this.operate = operate; } //処理の結果得られるOperandの文字列表現を返す。 public string GetOperandString() { return operate.Execute().GetOperandString(); } } public interface Operator { Operand Execute(); } //処理の実行 public class Plus : Operator { private Operand operand1 = null; private Operand operand2 = null; public Plus(Operand operand1, Operand operand2) { this.operand1 = operand1; this.operand2 = operand2; } public Operand Execute() { return new Ingredient(this.operand1.GetOperandString() + " + " + this.operand2.GetOperandString() + ""); } } class Program { static void Main(string[] args) { Expression expression1 = new Expression(new Plus(new Ingredient("1"),new Ingredient("2"))); System.Console.WriteLine(expression1.GetOperandString()); Expression expression2 = new Expression(new Plus(expression1, new Ingredient("2"))); System.Console.WriteLine(expression2.GetOperandString()); System.Console.ReadKey(); } } } |
C# デザインパターン Command
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 |
namespace ConsoleApplication2 { class Program { static void Main(string[] args) { Command command = new ConcreateCommand(); Receiver receiver = new ConcreateReceiver(); command.SetReceiver(receiver); Invoker invoker = new Invoker(command); invoker.execute(); } } /* Command 他のオブジェクトへのメソッド呼び出しとパラメータをオブジェクト化する。 */ public class Invoker // Commandの呼び出し { private Command command; public Invoker(Command command) { this.command = command; } public void execute() { this.command.Execute(); } } public interface Command //命令 { void SetReceiver(Receiver receiver); void Execute(); } public class ConcreateCommand: Command // 具体的な命令 { Receiver receiver; public void SetReceiver(Receiver receiver) { this.receiver = receiver; } public void Execute() { receiver.Action(); } } public interface Receiver //Commandの受信者 { void Action(); } public class ConcreateReceiver : Receiver //具体的な受信者 { public void Action() { } } } |
ざっくりまとめると、commandにreceiverを渡す。(commandがreceiverを保持)
渡し方は、Command cmd = new ConcreateCommand(receiver)
あるいは、上記のようなSetReceiver(receiver)とか。
そして、commandのExecute()の中でreceiverのAction()を呼ぶ。
Invokerは呼び出しで、そこからcommandのExecute()を呼ぶ。
処理の実体はreceiverのAction()の中。
C# Proxy
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 |
namespace ConsoleApplication2 { class Program { static void Main(string[] args) { Subject subject = new Proxy(); subject.Request1(); subject.Request2(); } } /* Proxy 代理人 */ interface Subject//ProxyとRealSubject共通のインターフェース { void Request1(); void Request2(); } public class Proxy : Subject //Clientからの処理を実行。 { public void Request1() { System.Console.WriteLine("this is proxy1"); } public void Request2() { //代理人に処理を任せる。 RealSubject realsubject = new RealSubject(); realsubject.Request2(); } } public class RealSubject : Subject //Proxyで処理できない場合処理。 { public void Request1() { System.Console.WriteLine("this is real proxy1"); } public void Request2() { System.Console.WriteLine("this is real proxy2"); } } } |
C# Flyweight
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 |
namespace ConsoleApplication2 { class Program { static void Main(string[] args) { } } /* Flyweight イミュータブルなクラス(フィールド値が不変のような)を再利用する。 */ public class Flyweight{ } public class FlyweightFactory { private FlyweightFactory f = new FlyweightFactory(); private FlyweightFactory(){ } private System.Collections.Generic.Dictionary<int,Flyweight> dic = new System.Collections.Generic.Dictionary<int, Flyweight>(); public FlyweightFactory GetInstance() { return f; } public Flyweight GetFlyweight(int key) { Flyweight f = dic[key]; if(f == null) { f = new Flyweight(); dic.Add(key, f); } return f; } } } |
C# State
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 |
namespace ConsoleApplication2 { class Program { static void Main(string[] args) { } } /* State 状態管理のクラス */ public class Context//具体的な状態(ConcreateState)を保持する。 { public State state; public void ChangeState(State state) { this.state = state; } public void Action() { this.state.Action(); } } public interface State//状態を表すクラス { void Action(); } public class ConcreateState1: State//具体的な状態 { public void Action() { //状態1 } } public class ConcreateState2 : State//具体的な状態 { public void Action() { //状態2 } } } |