2014年8月10日日曜日

MarkdownNote0.0.0.2

今日も更新

検索/置換/表の挿入機能の追加

今後の予定

プレビューがあやしい&使えなくしてる機能の修正
ファイルのエンコードを変更できるように
シンタックスハイライトの追加
見出しの一覧/移動ができるように

怪しい英語から日本語へ切り替えれるようにLanguageファイルの追加



2014年8月8日金曜日

MarkdownNote0.0.0.1


最近Markdown記法にハマっているのでタブ切り替え型のエディターを作成中
とりあえず形になってきたのでうpしてみました




動作には.netFramework4.0以上が必要です
ここからダウンロード

2014年4月23日水曜日

引き継いだAccessのシステムが激遅な件

15年近く前に外注に出したAccessのシステムの保守を引き継いだ
データのサイズは400MBを超えていて、数万件のデータから1レコードを検索をしようと思ったら1分近くかかるシステムだった。
外注の書いたコードか前任者の追加コードが原因かは今となってはわからない(仕様書もない)が
VBAソースコードを見直してみたらナポリタンの匂いがした

TCP Monitor Plusをダウンロードして、ファイルサーバーとクライアントPCのパケットをモニタリングしてみたところ1レコードの検索で80MBのデータを受信していることが判明(/・ω・)/

見直しをしてみたらテーブルのフィールドに適切なインデックスが設定されておらずRecordsetでFilter使いまくりだった

Indexの有無とFilter使った場合でどんだけ違うのかをテストしてみた

新しいAccessファイルを作りテーブル1にフィールド1~6を追加
フィールド1はインデックスをはい (重複あり)に指定

下のコードで500000件のテストデータを入れ込んだ

  1. Option Compare Database  
  2. Option Explicit  
  3.   
  4. Sub TestData()  
  5.   
  6.     Dim db As DAO.Database  
  7.     Set db = CurrentDb  
  8.     
  9.     Dim l As Long  
  10.     For l = 0 To 500000  
  11.         
  12.         db.Execute ("INSERT INTO テーブル1 (フィールド1,フィールド2,フィールド3,フィールド4,フィールド5,フィールド6) " & _  
  13.                     "VALUES ('" & GetGUID() & "','" & GetGUID() & "','" & GetGUID() & "','" & GetGUID() & "','" & GetGUID() & "','" & GetGUID() & "')")  
  14.     
  15.     Next  
  16.   
  17. End Sub  
  18.   
  19. '下のサイトを参考にさせてもらいました  
  20. 'http://maeda0414.blog.fc2.com/blog-entry-26.html  
  21. Public Function GetGUID() As String  
  22.     GetGUID = Mid$(CreateObject("Scriptlet.TypeLib").Guid, 2, 36)  
  23. End Function  
このファイルをファイルサーバに置き
クライアント側にも新しいAccessファイルを作りモジュールに下のテストコードを書く

  1. Option Compare Database  
  2. Option Explicit  
  3.   
  4. Public Sub Test1()  
  5.   
  6.     Dim db As DAO.Database  
  7.     Dim rs As DAO.Recordset  
  8.     
  9.     Set db = CurrentDb  
  10.     
  11.     'インデックスを設定したフィールドを条件にして直にクエリ文を書いた  
  12.     Set rs = db.OpenRecordset("SELECT * FROM テーブル1 WHERE フィールド1 = '884EBDD8-0516-480D-9C13-6F2EF60B2202'")  
  13.       
  14.     Do Until rs.EOF  
  15.         Debug.Print ("Test1 " & rs!ID)  
  16.         rs.MoveNext  
  17.     Loop  
  18.     
  19. End Sub  
  20.   
  21. Public Sub Test2()  
  22.   
  23.     Dim db As DAO.Database  
  24.     Dim rs As DAO.Recordset  
  25.     
  26.     Set db = CurrentDb  
  27.     
  28.     'インデックスの設定をしていないフィールドを条件にして直にクエリ文を書いた  
  29.     Set rs = db.OpenRecordset("SELECT * FROM テーブル1 WHERE フィールド2 = '7BFD061C-711E-404F-89D3-0973CADFF5F6'")  
  30.       
  31.     Do Until rs.EOF  
  32.         Debug.Print ("Test2 " & rs!ID)  
  33.         rs.MoveNext  
  34.     Loop  
  35.         
  36. End Sub  
  37.   
  38. Public Sub Test3()  
  39.   
  40.     Dim db As DAO.Database  
  41.     Dim rs As DAO.Recordset  
  42.     
  43.     Set db = CurrentDb  
  44.     
  45.     'Filterプロパティにインデックスを設定したフィールドの条件を書いた  
  46.     Set rs = db.OpenRecordset("テーブル1")  
  47.     rs.Filter = "フィールド1 = '884EBDD8-0516-480D-9C13-6F2EF60B2202'"  
  48.     Set rs = rs.OpenRecordset  
  49.       
  50.     Do Until rs.EOF  
  51.         Debug.Print ("Test3 " & rs!ID)  
  52.         rs.MoveNext  
  53.     Loop  
  54.     
  55. End Sub  
  56.   
  57. Public Sub Test4()  
  58.     
  59.     Dim db As DAO.Database  
  60.     Dim rs As DAO.Recordset  
  61.     
  62.     Set db = CurrentDb  
  63.     
  64.     'Filterプロパティにインデックスの設定していないフィールドの条件を書いた  
  65.     Set rs = db.OpenRecordset("SELECT * FROM テーブル1 WHERE フィールド2 = '7BFD061C-711E-404F-89D3-0973CADFF5F6'")  
  66.       
  67.     Set rs = db.OpenRecordset("テーブル1")  
  68.     rs.Filter = "フィールド2 = '7BFD061C-711E-404F-89D3-0973CADFF5F6'"  
  69.     Set rs = rs.OpenRecordset  
  70.     Do Until rs.EOF  
  71.         Debug.Print ("Test4 " & rs!ID)  
  72.         rs.MoveNext  
  73.     Loop  
  74.         
  75. End Sub  

リンクテーブルを張ってテスト

結果
Test1 送受信量 226KB
Test2 送受信量 153MB
Test3 送受信量 157MB
Test4 送受信量 157MB

まとめ
適切なインデックス設定を行う事とRecordsetのFilterは使わないと心に誓った

2014年3月12日水曜日

忘れていた

ブログが三日坊主になっていたので更新
モジュラス103もそのうち更新するよてえい

電子タバコおいしいれす(^q^)

C#で9DSRの計算

  1. /// <summary>  
  2. /// 9DSR 計算  
  3. /// NW-7  
  4. /// </summary>  
  5. /// <param name="Value">/// <returns></returns>  
  6. public static string Get9DSR(string Value)  
  7. {  
  8.     bool result = Regex.IsMatch(Value, @"^[0-9]+$");  
  9.     if (!result)  
  10.     {  
  11.         return null;  
  12.     }  
  13.     return (ulong.Parse(Value) % 9 == 0 ? 0 : 9 - (int.Parse(Value) % 9)).ToString();  
  14. }  

C#でルーンズ(モジュラス10/ウェイト2)の計算

  1. /// <summary>  
  2. /// ルーンズ(モジュラス10/ウェイト2 計算  
  3. /// NW-7  
  4. /// </summary>  
  5. /// <param name="Value">/// <returns></returns>  
  6. public static string GetModulus10Weight2Runes(string Value)  
  7. {  
  8.     bool result = Regex.IsMatch(Value, @"^[0-9]+$");  
  9.     if (!result)  
  10.     {  
  11.         return null;  
  12.     }  
  13.   
  14.     long checkDigit = 0;  
  15.   
  16.     for (int i = 0; i < Value.Length; i++)  
  17.     {  
  18.         if (i % 2 == 0)  
  19.         {  
  20.             int x = int.Parse(Value.Substring(Value.Length - 1 - i, 1)) * 2;  
  21.             //10以上の場合、桁ごとに加算  
  22.             if (10 <= x) x = 1 + (x % 10);  
  23.   
  24.             checkDigit += x;  
  25.         }  
  26.         else  
  27.         {  
  28.             checkDigit += int.Parse(Value.Substring(Value.Length - 1 - i, 1));  
  29.         }  
  30.     }  
  31.   
  32.     checkDigit = 10 - (checkDigit % 10);  
  33.   
  34.     checkDigit = checkDigit == 10 ? 0 : checkDigit;  
  35.   
  36.     return checkDigit.ToString();  
  37. }  

C#で加重モジュラス11の計算

  1. /// <summary>  
  2. /// 加重モジュラス11 計算  
  3. /// NW-7  
  4. /// </summary>  
  5. /// <param name="Value">/// <returns></returns>  
  6. public static string GetWeightedModulus11(string Value)  
  7. {  
  8.     bool result = Regex.IsMatch(Value, @"^[0-9]+$");  
  9.     if (!result || Value.Length > 12)  
  10.     {  
  11.         return null;  
  12.     }  
  13.   
  14.     int[] weight1 = { 2, 6, 3, 5, 4, 8, 7, 10, 9, 5, 3, 6, };  
  15.     int[] weight2 = { 9, 5, 8, 6, 7, 3, 4, 10, 2, 6, 8, 5, };  
  16.   
  17.     try  
  18.     {  
  19.         int checkDigit = 0;  
  20.         for (int i = 0; i < 2; i++)  
  21.         {  
  22.             checkDigit = 0;  
  23.             for (int j = 0; j < Value.Length; j++)  
  24.             {  
  25.                 checkDigit += int.Parse(Value.Substring(Value.Length - 1 - j, 1)) * (i == 0 ? weight1[j] : weight2[j]);  
  26.             }  
  27.             checkDigit = checkDigit % 11;  
  28.   
  29.             if (checkDigit == 0) return "0";  
  30.             if (checkDigit != 1) break;  
  31.         }  
  32.   
  33.         return (11 - checkDigit).ToString();  
  34.     }  
  35.     catch  
  36.     { }  
  37.     return null;  
  38. }  

C#でモジュラス10/ウェイト2の計算

  1. /// <summary>  
  2. /// モジュラス10/ウェイト2 計算  
  3. /// NW-7  
  4. /// </summary>  
  5. /// <param name="Value">/// <returns></returns>  
  6. public static string GetModulus10Weight2(string Value)  
  7. {  
  8.     bool result = Regex.IsMatch(Value, @"^[0-9]+$");  
  9.     if (!result)  
  10.     {  
  11.         return null;  
  12.     }  
  13.   
  14.     int checkDigit = 0;  
  15.   
  16.     for (int i = 0; i < Value.Length; i++)  
  17.     {  
  18.         checkDigit += int.Parse(Value.Substring(Value.Length - 1 - i, 1)) * (i % 2 == 0 ? 2 : 1);  
  19.     }  
  20.   
  21.     checkDigit = 10 - (checkDigit % 10);  
  22.   
  23.     checkDigit = checkDigit == 10 ? 0 : checkDigit;  
  24.   
  25.     return checkDigit.ToString();  
  26. }  

C#でモジュラス11の計算

  1. /// <summary>  
  2. /// モジュラス11 計算  
  3. /// NW-7  
  4. /// </summary>  
  5. /// <param name="Value">/// <returns></returns>  
  6. public static string GetModulus11(string Value)  
  7. {  
  8.     bool result = Regex.IsMatch(Value, @"^[0-9]+$");  
  9.     if (!result || 6 > Value.Length)  
  10.     {  
  11.         return null;  
  12.     }  
  13.   
  14.     string val = Value.Substring(0, 6);  
  15.   
  16.     int checkDigit = 0;  
  17.     for (int i = 0; i < val.Length; i++)  
  18.     {  
  19.         checkDigit += int.Parse(val.Substring(i, 1)) * (7 - i);  
  20.     }  
  21.     checkDigit = checkDigit % 11;  
  22.   
  23.     if (checkDigit == 0)  
  24.     {  
  25.         return "1";  
  26.     }  
  27.     else if (checkDigit == 1)  
  28.     {  
  29.         return "0";  
  30.     }  
  31.     else  
  32.     {  
  33.         return (11 - checkDigit).ToString();  
  34.     }  
  35. }  

C#で9DRの計算

  1. /// <summary>  
  2. /// 9DR 計算  
  3. /// NW-7  
  4. /// </summary>  
  5. /// <param name="Value">/// <returns></returns>  
  6. public static string Get9DR(string Value)  
  7. {  
  8.     bool result = Regex.IsMatch(Value, @"^[0-9]+$");  
  9.     if (!result)  
  10.     {  
  11.         return null;  
  12.     }  
  13.   
  14.     return (ulong.Parse(Value) % 9).ToString();  
  15. }  

C#で7DSRの計算

  1. /// <summary>  
  2. /// 7DSR 計算  
  3. /// NW-7  
  4. /// </summary>  
  5. /// <param name="Value">/// <returns></returns>  
  6. public static string Get7DSR(string Value)  
  7. {  
  8.     bool result = Regex.IsMatch(Value, @"^[0-9]+$");  
  9.     if (!result)  
  10.     {  
  11.         return null;  
  12.     }  
  13.   
  14.     string value =(ulong.Parse(Value) % 7 == 0 ? 0 : 7 - (ulong.Parse(Value) % 7)).ToString();  
  15.   
  16.     return value;  
  17. }  

C#でモジュラス16の計算

  1. /// <summary>  
  2. /// モジュラス16 計算  
  3. /// NW-7  
  4. /// </summary>  
  5. /// <param name="Value">/// <returns></returns>  
  6. public static string GetModulus16(string Value)  
  7. {  
  8.     bool result = Regex.IsMatch(Value, @"^[0-9|\-|$|:|/|・|+|A-D]+$");  
  9.     if (!result)  
  10.     {  
  11.         return null;  
  12.     }  
  13.   
  14.     long digit = 0;  
  15.     for (int i = 0; i < Value.Length; i++)  
  16.     {  
  17.         digit += Array.IndexOf(modulus16CharList, Value[i]);  
  18.     }  
  19.   
  20.     string value = modulus16CharList[(digit % 16) == 0 ? 0 : 16 - (digit % 16)].ToString();  
  21.   
  22.     return value;  
  23. }  

C#で7DRの計算

  1. /// <summary>  
  2. /// 7DR 計算  
  3. /// NW-7  
  4. /// </summary>  
  5. /// <param name="Value">/// <returns></returns>  
  6. public static string Get7DR(string Value)  
  7. {  
  8.     bool result = Regex.IsMatch(Value, @"^[0-9]+$");  
  9.     if (!result)  
  10.     {  
  11.         return null;  
  12.     }  
  13.   
  14.     string value = (ulong.Parse(Value) % 7).ToString();  
  15.   
  16.     return value;  
  17. }