ハロの外部記憶インターフェイス

そろそろ覚える努力が必要かも…

Google Map Apiを利用してみる

諸事情により、Wep APIを利用するコーディングを試すことになったので、メモる

Google Cloud Platformの登録

Google Map Apiを利用するためにはGoogle Cloud Platformへの登録が必要、クレジットカード必須。 https://cloud.google.com 登録を完了すると、デフォルトのプロジェクトが生成される。

認証キーを生成する。

サイドメニューから「APIとサービス→認証情報」へ f:id:haronoid:20191006201447p:plain 認証情報を作成から、APIキーを選択し、認証キーを作成する。
APIキーの制限設定画面からはアプリケーション制限からHTTPやIPアドレスでの制限をかけれるらしい、とりあえず、テストだけにはなしで問題なし

Google Map Apiを有効にする。

サイドメニューから「APIとサービス→ライブラリー」へ f:id:haronoid:20191006201841p:plain 「Maps JavaScript API」を探して、「有効」にする。 f:id:haronoid:20191006202318p:plain 管理画面へ移動 f:id:haronoid:20191006203041p:plain これで、Javascript用Map Apiが利用可能になった。
用件によって「Geocoding API」や「Places API」の有効化が必要になる。

Map APIを利用して座標の地図を表示してみる。

HTML

googleapiが読まれたタイミングでinitMapが実行され、表示される

<div id="map" style="height:500px;width:500px;"></div>

<script>
    function initMap() {
    var MyLatLng = new google.maps.LatLng(34.7088812,135.4881584);
    var Options = {
        zoom: 15,      //地図の縮尺値
        center: MyLatLng,    //地図の中心座標
        mapTypeId: 'roadmap'   //地図の種類
    };
    var map = new google.maps.Map(document.getElementById('map'), Options);
}
</script>

<script src="http://maps.google.com/maps/api/js?key={API_KEY}&language=ja&callback=initMap"></script>

Geocoding APIを利用して、住所から座標を取得する方法

もともとこれをやって見るための準備だったので、これを有効にする。 f:id:haronoid:20191006204058p:plain これにより、Web APIからのResponseを取得する様にしてみる。

.NETのコンソールプロジェクトを作成し、必要なパッケージを追加する。

先ずはパッケージの追加 + Microsoft.AspNet.WebApi.Client + Newtonsoft.Json

レスポンス用クラスを宣言(Google GeocodeからのレスポンスのJson型)

    public class MyResponse
    {
        public List<AddressComponent> results { get; set; }
        public string status { get; set; }
    }

    public class AddressComponent
    {
        public List<address_components> address_components { get; set; }
        public string formatted_address { get; set; }
        public Geometry geometry { get; set; }
        public string place_id { get; set; }
        public List<string> types { get; set; }
    }

    public class Geometry
    {
        public Bounds bounds { get; set; }
        public Point location { get; set; }
        public string location_type { get; set; }
        public Bounds viewport { get; set; }
    }

    public class Bounds
    {
        public Point northeast { get; set; }
        public Point southwest { get; set; }
    }

    public class Point
    {
        public decimal lat { get; set; }
        public decimal lng { get; set; }
    }
    public class address_components
    {
        public string long_name { get; set; }
        public string short_name { get; set; }
        public List<string> types { get; set; }
    }

実行プログラム

    class Program
    {
        static HttpClient _client = new HttpClient();
        static List<String> _list = new List<string>();
        static Dictionary<String,string> _result = new Dictionary<String, string>();

        static void Main(string[] args)
        {
            _list.Add("東京タワー");
            _list.Add("543-0001");

            RunAsync().GetAwaiter().GetResult();
            foreach (var item in _result)
            {
                // JsonからNewtonsoft.Jsonを利用してDeserializeしている。下のresult3と結果は同じ
                var conv = Newtonsoft.Json.JsonConvert.DeserializeObject<MyResponse>(item.Value);
                Console.WriteLine($"{item.Key}=X:{conv.results[0].geometry.location.lat},Y:{conv.results[0].geometry.location.lng}");
            }
            Console.ReadLine();
        }

        static async Task<String> GetResultAsync(string address)
        {
            //Json形式で返す様にしている。
            HttpResponseMessage response = await _client.GetAsync(new Uri($"https://maps.googleapis.com/maps/api/geocode/json?address={address}&key={API_KEY}"));

            var result = response.EnsureSuccessStatusCode();
            var result2 = await response.Content.ReadAsStringAsync(); //Jsonの文字列を取得する。
            var result3 = await response.Content.ReadAsAsync<MyResponse>();  //Deserializeした結果を受け取る

            return result2;
        }

        static async Task RunAsync()
        {
             // BaseAddressは指定しているが、今回は毎回Full Urlを送っているため、何でも良い(はず)
            _client.BaseAddress = new Uri("https://maps.googleapis.com/maps/api/geocode/");
            _client.DefaultRequestHeaders.Accept.Clear();
            _client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));

            try
            {
                foreach (var item in _list)
                {
                    var result = await GetResultAsync(item);
                    _result.Add(item, result);
                }

            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

        }
    }

テスト用コードがいっぱい残っているが、とりあえず、ここまで

参考サイト developers.google.com docs.microsoft.com

トリガー作成メモ

TRIGGER作成

基本文法

CREATE TRIGGER [dbo].[TR_TABLE_NAME]
   ON  [dbo].[TABLE_NAME]
   AFTER INSERT,DELETE,UPDATE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for trigger here

END
GO

トリガーでのINSERT,UPDATE,DELETEの判定

少し面倒だが、こんな形で判定が可能だった

-- Insert
IF EXISTS (SELECT * FROM inserted) AND NOT EXISTS(SELECT * FROM deleted)
BEGIN 
    --inserted action
END

-- Update
IF EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)
BEGIN
    --updated action
END

-- Delete
IF EXISTS (SELECT * FROM deleted) AND NOT EXISTS(SELECT * FROM inserted)
BEGIN
    --deleted action
END

トリガーで更新値を変更する

自分自身へのUPDATEを発行する

UPDATE [dbo].[TABLE_NAME]
SET
    [CLM_NAME] = 'ABC'
FROM [dbo].[TABLE_NAME] T
INNER JOIN inserted I
    ON I.KEY = T.KEY

Styleの適用方法色々メモ

自分の以下の対象ターゲットのプロパティを固定する

青い四角のスタイルを設定する。

<Grid>
  <Grid.Resources>
    <Style TargetType="Rectangle">
      <Setter Property="Fill" Value="Blue"/>
    </Style>
  </Grid.Resources>
  <Rectangle Height="10" Width="10" />
</Grid>

キー名をつけてそれぞれのスタイルを指定する。

<Grid>
  <Grid.Resources>
    <Style x:Key="sty1" TargetType="Rectangle">
      <Setter Property="Fill" Value="Blue"/>
    </Style>
    <Style x:Key="sty2" TargetType="Rectangle">
      <Setter Property="Fill" Value="Red"/>
    </Style>
  </Grid.Resources>
  <StackPanel>
    <Rectangle Height="10" Width="10"  Style="{StaticResource sty1}"/>
    <Rectangle Height="10" Width="10"  Style="{StaticResource sty2}"/>
  </StackPanel>
</Grid>

Style.Triggerでのスタイル適用

プロパティの設定値によって、スタイルの変更を指定する。

<Grid.Resources>
    <Style TargetType="TextBox">
        <Style.Triggers>
            <Trigger Property="IsEnabled" Value="True">
                <Setter Property="Background" Value="White"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="False">
                <Setter Property="Background" Value="Silver"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</Grid.Resources>

Mi Band 4 中国版を英語化する(iOS)

AliExpress からMi Band 4(中国版)を購入したのは、良いが、表示がすべて中国語!

f:id:haronoid:20190724130428j:plain

さすがに表示が中国版のみってのはきつい。
本体でもMi Fitでも修正は出来ないみたいが、別のアプリ(公式?)からの変更方法が見つかったので、メモっとく

AmazToolsをダウンロード

まずはApp Storeからダウンロード。 f:id:haronoid:20190724132628p:plain

起動してから、Mi Band 4とBlutooth接続設定すればOK、 f:id:haronoid:20190724132754p:plain ここまでこれば、Watch Language設定が出来る。

結果

f:id:haronoid:20190724130501j:plain

.NetでBarcodeを作成し、印刷まで

目標

フリーパッケージでバーコードを作成し、印刷する。
有料パッケージだと色々便利だが、以前からAccessExcelに組み込まれたバーコードコントロールを使っているお客様には、金を使う気が無いので、却下になっている。

Nugetからパッケージをインストールする。

「barcode」で検索すると色々な候補が出てくるが、ほとんど有料だった。(IronBarcode, Spireなどなど)
結果、「Zen Barcode Rendering Framework」を使う。
種類に制約があるが、今回は問題なし

PM> Install-Package Zen.Barcode.Rendering.Framework -Version 3.1.10729.1

Nuget: https://www.nuget.org/packages/Zen.Barcode.Rendering.Framework/
GitHub: https://github.com/dementeddevil/BarcodeRenderingFramework

使い方

基本生成したバーコードをImage形式に保存する。
そのときに使うBarcodeDrawFactoryを切替ることで、生成されるバーコードも変わる仕組みらしい

using Zen.Barcode;

private Code128BarcodeDraw _barcode;
private Image _img;

public void CreateBarcode(string barcodeText, int barHeight = 50, int scale = 2)
{
    _barcode = BarcodeDrawFactory.Code128WithChecksum;
    _img = _barcode.Draw(barcode_text, barHeight, scale);
}

scaleはデフォルトだと少し小さめだったため、2にしてみた。

印刷用に編集

出来上がったバーコードはまさにバーコードのみだったため、印刷用イメージを作成する。
こんな感じにしたい
f:id:haronoid:20190622214659j:plain

//背景イメージ作成(バーコードイメージの余白になるように大きめにする。)
System.Drawing.Image backImg = new Bitmap(img.Width + 20, img.Height + 40, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Graphics g = Graphics.FromImage(backImg);
Brush b = new SolidBrush(Color.Black);
Font f = new Font("Courier", 13);
StringFormat sf = new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Far };

//背景クリア
g.Clear(Color.White);
g.DrawImage(img, 10, 10);   //バーコードを貼り付け
g.DrawString(bm.BarcodeText, f, b, backImg.Width / 2, backImg.Height, sf);  //バーコード文字を下部に配置

this.picBox.Image = backImg;

印刷

印刷もやり方探すのにかなり苦労したけど、最終的に作ったイメージを印刷で落ち着いた

//PrintDocumentを初期化し、プリントイベントを紐付ける。
var pd = new System.Drawing.Printing.PrintDocument();
pd.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.pd_PrintPage);
pd.Print();
pd.PrintPage -= this.pd_PrintPage;

//PrintDocument.Print();により、以下が実行される。
private void pd_PrintPage(Object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
  //ImageをeのGraphicsに当てたら、印刷された。
  e.Graphics.DrawImage(_img, 0, 0);
}

.NETでAccessをDBとして使う

必要になった理由

バッチでAccessのDBを読み取りSql Serverに更新するような要望が発生したため

Àccess DBを.NETで読み取る

以前のAccess2003(.mdb)の場合、「Microsoft.Jet.OLEDB.4.0」を使うらしいが、Access2010(.accdb)以降は、「Microsoft.ACE.OLEDB.12.0」をプロバイダとして使用するらしい

Microsoft Access Database Engine 2016インストール

以下のリンクからダウンロードした。
Download Microsoft Access Database Engine 2016 Redistributable from Official Microsoft Download Center 32bitバント64bit版があるが、64bitのOSには32bit版はインストール時エラーになった。

トラブル

Microsoft.ACE.OLEDB.12.0' プロバイダーはローカルのコンピューターに登録されていません。」
とエラーになるばかり、いろいろ調べて見ると、AniCpuやx64ではうまく動かず、実行時探しているバージョンは32bitだそう。
仕方ないので、64bit版は削除し、32bit版をインストールする。

AccessDatabaseEngine.exe /quiet

※64bit版OSでは「/quite」オプションで強制的にインストールが可能

一旦、これで接続は成功した。

ソース

プラットフォームはx86で作業しています。

using System.Data;
using System.Data.OleDb;

private const string CONNECTION_STRING = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\db\myDb.accdb";
private OleDbConnection _conn;

public void ExecuteSql()
{
    _conn = new OleDbConnection(CONNECTION_STRING);
    _conn.Open();

    OleDbCommand cmd =_conn.CreateCommand();
    cmd.CommandText = "SELECT * FROM MY_TABLE";

    DataTable dt;
    OleDbDataAdapter oda = new OleDbDataAdapter(cmd)
    oda.Fill(dt)

    _conn.Close();
}

パスワードがついているAccessの場合

「Jet OLEDB:Database Password」でパスワードを指定する

private const string CONNECTION_STRING = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\db\myDb.accdb;Jet OLEDB:Database Password=abc";

読取り専用モードでAccessを開きたい場合

「Mode」を指定してAccessを開く

指定値毎のモード

No Mode
Mode=1 Read
Mode=2 Share Deny None
Mode=3 ReadWrite
Mode=4 Share Deny None
Mode=5 Share Deny None
Mode=6 Share Deny None
Mode=7 Share Deny None
Mode=8 Share Deny Write
Mode=9 Share Deny None
Mode=10 Share Deny None
Mode=11 Share Deny None
Mode=12 Share Deny Read|Share Deny Write
Mode=13 Read|Share Deny Read|Share Deny Write
Mode=14 Share Deny None
Mode=15 Share Deny None
Mode=16 Share Deny None
Mode=17 Share Deny None
Mode=18 Share Deny None
Mode=19 ReadWrite|Share Deny None
private const string CONNECTION_STRING = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\db\myDb.accdb;Mode=1";

CodeLens解除、XAMLのUIデバックツールを非表示にする。

ソース上の参照数などの表示を非表示にする方法

VisualStudioのクラスやメソッドのソース上に参照数を表示する機能 f:id:haronoid:20190613103836p:plain

まあ、あると便利だが、ソースを表示するたびに行が広がり見づらくなったりするので、非表示にする。
「ツール」→「オプション」
「テキスト エディター」→「すべての言語」→「CodeLensを有効にする」のチェックを外す。
f:id:haronoid:20190613104020p:plain

XAML開発時に画面の上部に出る小さなウィンドウを非表示にする方法

「ツール」→「オプション」
「デバック」→「全般」→「XAMLのUIデバックツールを有効にする」のチェックを外す。
f:id:haronoid:20190613104720p:plain