・新規サービス作成手順
ソリューションフォルダ「Servers」を右クリックし、「追加」⇒「新しいプロジェクト」を選択する
「Vusual C#」カテゴリの「Windows」の配下にある「Windows サービス」を選び、名前を指定してOKを押下
プロジェクトのプロパティを開き、「アプリケーション」の「対象のフレームワーク」を「.NET Framework 4」
に変更する
最初にService1.csが作成されるので、デザイナで何もないところをクリックし、
プロパティウィンドウから「インストーラの追加」を選ぶ
生成されたProjectInstaller.csの"serviceProcessInstaller1"と"serviceInstaller1"から
数字の"1"を消して"serviceProcessInstaller"と"serviceInstaller"に名前を変える
serviceInstallerのプロパティに以下の文字列を指定する
DisplayName:サービス一覧画面に表示する名前
Description:サービス一覧画面に表示する説明。
ServiceName:サービスの識別名。プロジェクト名を指定する
StartType:インストール直後のスタートアップの種類
Accout:サービスの実行アカウントの種類を選択する
サービス登録(batで以下を実行)
C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil C:\Service.exe
pause
・バイナリ実装
16進数変換
Convert.ToByte(Convert.ToString(filever, 16), 16)
BCD変換
int i,j;
string s = "1001000043004865617020616E6420737461636BA5";
len = s.Length / 2;
byte[] num16 = new byte[len];
j = 0;
for ( i = 0; i < len; i++ )
{
num16[i] = Convert.ToByte(s.Substring(j, 2), 16);
j += 2;
}
バイナリ書き込み
using(MemoryStream st = new MemoryStream())
using(BinaryWriter bw = new BinaryWriter(st))
{
}
using(FileStream fs = new FileStream(filePath, FileMode.Append))
{
st.CopyTo(fs);
}
Datatable
文字列の重複削除
dataTable.AsEnumerable().Select(row =>
row.Field<string>("MOJIRETSU")).Distinct().Count();
日付の重複削除
dataTable.AsEnumerable().Select(row =>
row.Field<DateTime>("HIZUKE").Date).Distinct().Count();
日付の抽出
dataTable.Select("HIZUKE >= #" + DateTime.Parse("2015/08/15" + "# AND HIZUKE < #" +
"2015/08/15" + "#").Count()
親子関係の考え方
A(A.1(A.1.1),A.2(A.2.2)....)
第二階層(A.1、A.2...)の数=Aの件数
更新日付が最新のものを複数テーブルの更新日付から取得
Oracle
SELECT
UPD_DATE
FROM
(
SELECT
UPD_DATE
FROM
(
SELECT
MSMR.UPD_DATE
FROM
TABLEA MSMR
WHERE
MSMR.UPD_DATE = (SELECT MAX(UPD_DATE) FROM TABLEA)
UNION ALL
SELECT
MSMN.UPD_DATE
FROM
TABLEB MSMN
WHERE
MSMN.UPD_DATE = (SELECT MAX(UPD_DATE) FROM TABLEB)
) A
ORDER BY UPD_DATE DESC
)
WHERE
ROWNUM = 1;
降順データ取得
Oracle
SELECT
T.COLUMN1, T.COLUMN2
FROM
(
SELECT
TABLE1.COLUMN1, TABLE1.COLUMN2
FROM
TABLE1
ORDER BY
TABLE1.COLUMN2 DESC
) T
WHERE
ROWNUM <= 2;
SQL SERVER
カーソル
一時テーブルに入れたデータを順次取得して、
テーブルからのデータの取得処理に使う
1.一時テーブル定義
2.一時テーブルに条件を格納(INSERT)
3.一時テーブルにカーソルセット
4.一時テーブルから順次取得した値(条件)で、テーブルからデータを取得
/* カーソル宣言 */
Declare dataCursor Cursor For
Select
dataType
From #dataView
Open dataCursor
Fetch Next From dataCursor
Into @dataType
While @@FETCH_STATUS = 0
Begin
Fetch Next From dataCursor
Into @dataType
End
・Excelで、アプリケーションを作成する際の注意点
Excelを常時起動させたりすると、
他のエクセルをOpen⇒Closeした際に同じインスタンスの他BookのExcelが
全て閉じられてしまい、予期せぬ状態になりかねない
⇒お客さんに別プロセスで起動させる
スタートメニュー⇒「プログラムとファイルの検索」の窓に、「regdit」と入力
「HKEY_CLASSES_ROOT」⇒Excel.Sheet.12⇒Shellの上で右クリックして、
「新規」にカーソルを乗せ、「キー」をクリック
「別窓で開く」など、任意の名前を付ける
「別窓で開く」を右クリックして、同じく「新規」にカーソルを乗せ「キー」をクリックする
(ここでは必ず名前をcommandと入力する事)
commandを選択した状態で、右側にある「既定」をダブルクリックする
"EXEのフルパス" /x "%1" と入力する
https://quartet-communications.com/info/topics/21941
・定期払い戻しの考え方
定期払い戻し額=0
SF残額 >= 手数料(手数料なしON)
※定期払い戻し能力なし、
SFのみで払い戻した方が払戻額が大きい場合
定期払い戻し額 = 0
SF残額 >= 手数料
※定期払い戻し能力なし、
SFのみで払い戻した方が払戻額が大きい場合
定期払い戻し額 = 0
SF残額 < 手数料
※定期払い戻し能力なし、
SFのみで払い戻した方が払戻額が大きい場合
定期払い戻し額 > 0
定期払い戻し額+SF残額 <= 手数料
※SFのみで払い戻した方が払戻額が大きい場合
定期払い戻し額 > 0
定期払い戻し額+SF残額 > 手数料
定期払い戻し額 <= 手数料
※SFのみで払い戻した方が払戻額が大きくなりうる場合
定期払い戻し額 > 0
定期払い戻し額+SF残額 > 手数料
定期払い戻し額 > 手数料
※定期払い戻し含む払い戻しの方が大きくなる場合
・Visual Studioで使用しているtrnames.oraの場所
sqlplus @?
と実行して出てくるパスを指定
・テーブル作成 Oracle
表領域(USER01)をファイル名「USER01.dbf」、100MBのサイズで作成する
CREATE TABLESPACE IBKIC_DTI
DATAFILE 'C:\IBKIC_DTI.dbf' SIZE 100M
SEGMENT SPACE MANAGEMENT AUTO
・DB接続時に必要 Oracle
<add key="DBConnectionTimeout" value="10" />
<add key="DBCommandTimeout" value="10" />
⇒リトライ処理も
・交通系用語
飛びつき
定期外から定期区間内へ
乗り越し
定期内から定期外へ
飛びつき乗り越し
定期外⇒定期内⇒定期外
電子スターフ
車内のディスプレイ
・再現確認反省
再現確認方法見直し
まずは手順通りに再現確認
そうでなければ、どのような条件なら再現するか無理やりDEBUGオードで場所を変えてもいいので再現確認する
※仮に修正済みで再現しない場合でも、
再現しうる条件を順番に提起し、
最終的にAがBに変更になったため、再現はできない旨報告する
・GYAOとABEMAの違い
GYAO:CMなし、コンテンツ見放題
ABEMA:CM、プレミアム(過去視聴分)
・気づかなかった
integer⇒long
なるべく現地の環境に合わせて試験をする
⇒タスクスケジューラで起動される、等
数値のカンマ区切り
左寄せ、中央寄せ、右寄せ
帳票の確認方法
⇒何が出るのか正しくて何が出ないのが正しいのかを確認する
画面と帳票の比較
帳票同士の比較
・一部文字列抽出
=MID(D1,LEN("hogehoge")
・キャッシュクリア SQLSERVER
DBCC DROPCLEANBUFERS
DBCC FREEPROCCASHE
・気づかなかった
期限切れログデータ削除
非同期
列挙型の値変更
タイムアウト
リトライ
DB,WEBAPIからデータ取得時 outofmemory
非同期の必要性 還元データ
テスト 罫線の確認
テスト 日付確認 今日以外にしてもちゃんと今日以外の日付が出るか
テスト 計算式
テスト ~しながら...を変えたときに正しく変わること
計登板後_系統番号が違う場合、系統名称のみ違う場合
カレンダー画面と計上日を変更して作成ボタンを押下した場合の挙動
⇒背景色が白なので、予約可能として処理されてしまう
カレンダーは常時最新でない為、取得しに行ってエラーだった場合に
どうするか⇒一件でもエラーならエラーとするか、Oracleでtnsnames.ora
で接続できない
⇒datasource内を直接指定
帳票:出すものがないなら0件エラーを出す
スクリプトをお客さんに出す時に注意
Use [テーブル名]
go
を必ず入れる
・C# Tips
DBからのデータ読み出し高速化
AsNoTracking()
IEnumerable<IEnumerable<Town>> towns = dbContext.Towns.AsNoTracking().OrderBy(t => t.TownID).Batch(200000);
ストアド作成時の注意事項
結合したデータがNULLだった場合に、何を出すか確かめておく
⇒数値の場合はゼロ
⇒文字列の場合は~コード等
例)路線名がNULLなら路線番号
・数値変換
16進数を10進数に変換
0x15
1*16+5
⇒10進数 21
10進数を16進数に変換
21*16=1...5
⇒16深栖 15
BCD
0x15
⇒10進数 15
・Winmergeで抜け漏れが発生しないようにする
フォント:HGゴシックM
差異色:青
・IDENTITY属性を指定している場合のINSERT
// IDENTITY属性を指定している列名保持用
string indexColumnName = "";
MetadataProperty storeGeneratedPatternProperty = null;
foreach(var item in entry.EntitySet.ElementType.Members)
{
storeGeneratedPatternProperty = item.MetadataProperties.Where(f =>
f.Name.Contains("StoreGeneratedPattern")).FirstOfDefault();
if(storeGeneratedPatternProperty != null &&
Convert.ToString(storeGeneratedPatternProperty.Value) == "Identity")
{
indexColumnName = item.Name;
// IDENITY属性を指定された列に値を格納しても正常に動作するようにSQL文を変更
sql = string.Format("SET IDENTITY_INSERT {0} ON ", tableName) + sql;
break;
}
}
・実行するメソッドをXMLで管理する
<?xml version="1.0" encoding="utf-8"?>
<TaskPool>
<TaskSet TaskSeID="0001" TaskSetName="処理開始" UseFormIDs="Form1"
StartTaskItemID="0001" CommonTask="false" ReportTaskNumber="1" NameSpace="Task"
CardType="" PatternNames="">
<OperationJudgePool>
<OperationJudge MethodID="JudgeMethod1" ErrorMessage="Err_0001"
SuggestionMessage="Sug_0001" MethodComment="判定" />
</OperationJudgePool>
<TaskCheckPool>
<TaskCheck MethodID="CheckMethod1" MethodArg="" MethodComment="エラーリカバリ" />
</TaskCheckPool>
<TaskItem TaskItemID="0001" TaskItemName="読み込み開始" UseFormID="Form1">
<Preload>
<Action MethodID="Method1" MethodArg="0001" MehodComment="メソッド(0001)" />
</Preload>
<Loaded />
<StatusUpdate />
<DecideMethod />
<Buton1Pushed>
<Action MethodID="Transfer" MethodArg="0007" MethodComment="処理終了" />
</Buton1Pushed>
<Button2Pushed />
<Leaved />
</TaskItem>
<TaskItem TaskItemID="0007" TaskItemName="処理終了" UseFormID="Form2">
<Preload>
<Action MethodID="Method2" MethodArg="" MehodComment="機能終了" />
</Preload>
<Loaded>
<Action MethodID="Method3" MethodArg="Form1" MehodComment="前画面終了" />
<Loaded />
<StatusUpdate />
<DecideMethod />
<Buton1Pushed />
<Button2Pushed />
<Leaved />
</TaskItem>
</TaskSet>
</TaskPool>
・Task管理用XML
埋め込まれたリソースに設定し、
名前空間を省略せずに記載するとXMLを取得できる
・DBのログを削除する方法
データベース⇒タスク⇒圧縮⇒ファイル
ファイルの種類:ログ
未使用領域を解放する
・Visual Studioのビルドイベント
既にコピー先に存在する場合は失敗するので注意。 /yで上書き確認しないようにしておく必要がある
copy "$(ProjectDir)log.config" "$(OutDir)log.config" /y
・変換処理
16進数文字列からbyte配列を生成
if(string.IsNullOrEmpty(str))
{
return null;
}
int len = str.Length / 2;
byte[] bytes = new byte[len];
for(int i = 0, j = 0; j < len; i++, j += 2)
{
bytes[i] = Convert.ToByte(str.Substring(j, 2), 16);
}
return (byte[]).bytes.Clone();
・変換処理
byte配列から16進数文字列を生成
if(null == bytes)
{
return string.Empty;
}
StringBuilder sb = new StringBuilder(bytes.Length * 2);
foreach(byte b in bytes)
{
sb.Append(string.Format("{0:X2}", Convert.ToInt32(b));
}
return sb.ToString();
・Entity Framework
ストアドプロシージャの戻り値を型で取得する方法
edmxのデータベース更新でストアドを取得した後、
モデルブラウザー~、store-ストアドプロシージャ―関数インポート
列情報の取得+複合型の作成
・C# ストアド ジェネリックス
objectParameter[] para;
ObjectResult<T> result = this.m_objectContext.ExecuteFunction<T>(ストアド名, para);
・list.sortの書き方
result.Sort((x, y) => x.USAGE_DATE.CompareTo(y.USAGE_DATETIME));
・現在格納されているデ―タのINSERT文生成方法
データベースを右クリックし、メニューから[タスク]⇒[スクリプトの生成(E)。。。]
データベース全体または特定テーブルのいずれかを選択して次へ
詳細選択をクリックして、スクリプトを作成するデータの種類を[データのみ]に変更する
確認画面で次へを押すと出力開始
・Excelのキャプチャ(ヘッダ、フッタあり)
PDFで保存⇒Snipping Tool
・Excel 保存時 通貨 カッコ つけさせない
ExBook.SaveAs(i_saveFileName, Local:true);
・Excel 勤務時間を三等分したい場合
シリアル値を分単位に直す
分単位にした値/3を再びシリアル値に戻す
※
・シリアル値を分単位にする方法⇒シリアル値*(24 * 60)
・分単位をシリアル値に戻す⇒シリアル値/(24*60)
・分単位にした値を/3の値を求める⇒QUOTIENT(4G8*24*60, 3)
・割り切れる値かどうか判定する方法⇒/3した結果が1かどうかで判定
⇒ROUND(MOD($G8*24*60, 3), 0)
・sqlserverストアド インデックスを張る方法
・実行して結果まで出るクエリ部を全選択
・ツールバーの推定実行プランの表示を選択
・GUI画面の中で、「不足しているインデックス」を右クリック、詳細を表示する
・インデックスのコマンドが取得できるので実行する