2017年12月25日月曜日

Angularで日時のスライダーを作りたい

ION-Rangeなるものがあるけど、これは数値しか扱えない。
 同じ感じで日時を扱いたい。
 AngularJSだとこのサイトが参考になりそうだが、4+だとどうなるか。

ちなみに、やりたいのはまさしくこれ

 ION-Rangeをベースに独自コンポーネントを作るしかないか。

2017年12月22日金曜日

IONIC3、Leaflet、Bingmapsを使って地図を表示するまで

【前提】
node.js、Ionic3はインストール済み。

【手順】
1.プロジェクトを作成
以下のコマンドを実行してIonicプロジェクトを作成。
AndroidとかiOSのプラットフォームを追加するか聞かれるけど全てNo。
ionic start MyIonicProject tutorial

2.npmパッケージ追加
packages.jsonのdependenciesに以下を追記。
    "@types/leaflet": "1.2.3",
    "@asymmetrik/ngx-leaflet": "2.5.3",
    "leaflet": "1.2.0",
    "leaflet-bing-layer": "3.2.0"

3.LeafletのCSSをコピーしてlink
packages.jsonに以下を追記。
  "config": {
      "ionic_copy": "./config/copy.config.js"
  }

packages.jsonから「config/copy.config.js」の場所にファイルを作り、以下の内容を記述。
module.exports = {
    copyAnimateCss: {
        src: './node_modules/leaflet/dist/leaflet.css',
        dest: '{{BUILD}}'
    }
}

index.htmlのヘッダにcssへのリンクを追記。
<link href="build/leaflet.css" rel="stylesheet">

4.hello Ionicページに地図を表示
src\pages\hello-ionicのファイルを修正し、地図を表示する。
■hello-ionic.html
<ion-content padding>
    <div id="map" style="width:100%; height:100%;"></div>
</ion-content>


■hello-ionic.ts
import { Component, ViewChild, ElementRef } from '@angular/core';
import NGX from '@asymmetrik/ngx-leaflet';
import L from 'leaflet';
import 'leaflet-bing-layer';

@Component({
    selector: 'page-hello-ionic',
    templateUrl: 'hello-ionic.html'
})

export class HelloIonicPage {
    map: any;

    constructor() {
    }
    
    ionViewDidEnter() {
        this.loadmap();
    }

    loadmap() {
        this.map = L.map("map").setView([35.658581, 139.745433], 16);
        L.tileLayer.bing('BingMasのキー', {
            maxZoom: 18
        }).addTo(this.map);
    }
}

ここまでやったら実行。
ionic serve

2017年11月17日金曜日

気になること

気になることのリスト

1.Node-RED
  ⇒JavaScriptのノンプログラミング開発ツール?

2.IQP
  ⇒IoT向けプラットフォームと画面のノンプログラミング作成クラウドサービス

3.Toami
  ⇒IQPと同様。docomoが提供しているサービスもある。


2017年10月26日木曜日

GitBucketを使ってみる(準備編)

社内でソース管理の相談をされたので、Gitを提案してみようと思う。
コマンドラインを使うような人はいないため、管理システムとしてGitBucketを使うことにした。
採用の理由は以下の2点。情シス的には楽なのが一番。
 ・環境構築が簡単(WindowsクライアントにJREをインストールしてwarファイルを実行すれば使える)
 ・バックアップが楽(フォルダ丸ごとコピーでいい)

【GitBucketとは】
たけぞうさんが開発されているGitHubクローン。
GitHub

【とりあえず動かす】
1.JREをインストール
2.gitbucket.warをダウンロードして適当なフォルダにコピー
3.同じフォルダに以下の内容のバッチファイルを作成して実行
java -jar gitbucket.war
4.ブラウザで「http://ホスト名:8080」にアクセス
5.id:root / Pass:root でログイン
 ※3はサービス化することもできる(参考1参考2

【サービス化する】
サービス化には(有)軟式さんのsexeを使う。(窓の杜
1.sexeをダウンロード
2.sexeを実行してサービスに設定
 ファイル:java
 起動時オプション:-jar c:\gitbucket.war ← 絶対パスで指定

【ポートを変える】
すでにポート8080が使われている場合、ポートの変更が必要。
引数でポートを指定することができる。
sexeの起動時オプションを変更することで対応。
 起動時オプション:-jar c:\gitbucket.war --port=8181

【複数のGitBucketを起動する場合】
部署のしがらみなんかで、1台のマシンで2つのGitBucketを動かしたい場合の手順。
管理情報の場所は環境変数GITBUCKET_HOMEで設定できるが、あくまで設定は1つのみ。
なので、起動時に環境変数を変えることで対応してみる。
ポイントはsetlocalで環境変数をローカル化するところ。
1.sexeを実行して部署AAAのサービスを設定
 ファイル:c:\windows\system32\cmd.exe
 起動時オプション:/c "@setlocal&SET GITBUCKET_HOME=C:\gitbucket\settings\AAA&C:\Program Files\Java\jre1.8.0_151\bin\java.exe -jar C:\\gitbucket.war --port=8181&@endlocal"
2.sexeを実行して部署BBBのサービスを設定
 ファイル:c:\windows\system32\cmd.exe
 起動時オプション:/c "@setlocal&SET GITBUCKET_HOME=C:\gitbucket\settings\BBB&C:\Program Files\Java\jre1.8.0_151\bin\java.exe -jar C:\\gitbucket.war --port=8182&@endlocal"


2017年10月12日木曜日

Kii Cloud SDKをTypescript(Angular2+)で使う手順

Kii Cloud SDKをTypescriptで使えるようにするための手順。
Angular2+でOnsenUIを使うまでが終わっている前提で進めます。
ライブラリのバージョンは以下の通り。
"kii-cloud-sdk": "^2.4.11",
"@types/kii-cloud-sdk": "^2.4.35",

1.Kii Cloud SDKを導入
以下のコマンドを実行。
npm install --save kii-cloud-sdk

2.TypeScriptの型定義を導入
以下のコマンドを実行。
npm install --save @types/kii-cloud-sdk

3.Webpackの定義を修正 VSCodeで型定義が読めているが、実行すると以下のエラーが発生。
ERROR in C:/kii-test/src/app/app.component.ts (19,7): Cannot find name 'Kii'.
WebpackがNodeのライブラリを見てるため発生するらしいので、Webpackの定義を変更して対応。
参考:Angular build cannot resolve '../package' and 'child_process'

ただし標準だとスケルトンとやらで隠れているので、以下のコマンドを実行してプロジェクト個別のファイルとして取り出す。
ng eject
参考:Angular/TypeScriptプロジェクトのコンパイルの仕組み

プロジェクトルートに"webpack.config.js"ができるので、以下の記述を追加。
externals: {
    'xhr2': 'XMLHttpRequest',
    'xmlhttprequest': 'XMLHttpRequest',
    'node-fetch': 'fetch',
    'text-encoding': 'TextEncoder',
    'urlutils': 'URL',
    'webcrypto': 'crypto'
}

4.Typescript型定義修正
Typescriptのコンパイルエラーになるので"node_modules/@types/kii-cloud-sdk/index.d.ts"を修正。
先頭に以下の行を追加する。
export = KiiCloud;
export as namespace KiiCloud;

5.kii-cloud-sdk.jsのソースを修正 "node_module/kii-cloud-sdk/KiiSDK.js"の最後の方のコードを修正。
// Following code was generated by build.sh for running on Node.js
(function() {
var b = ((typeof module) !== "undefined") && (module !== null);
if (b && module.exports) {
  /*
  module.exports = {
    exportedClasses: ['ForTest', 'Kii', 'KiiACL', 'KiiACLEntry', 'KiiACLWithToken', 'KiiAnalytics', 'KiiAnonymousUser', 'KiiAnyAuthenticatedUser', 'KiiAppAdminContext', 'KiiBucket', 'KiiBucketWithToken', 'KiiClause', 'KiiEncryptedBucket', 'KiiEncryptedBucketWithToken', 'KiiErrorParser', 'KiiGeoPoint', 'KiiGroup', 'KiiGroupWithToken', 'KiiObject', 'KiiObjectWithToken', 'KiiPushInstallation', 'KiiPushInstallationWithToken', 'KiiPushSubscription', 'KiiPushSubscriptionWithToken', 'KiiQuery', 'KiiSCNFacebook', 'KiiSCNGoogle', 'KiiSCNQQ', 'KiiSCNRenRen', 'KiiSCNTwitter', 'KiiSDKClientInfo', 'KiiServerCodeEntry', 'KiiServerCodeExecResult', 'KiiSocialConnect', 'KiiSocialConnectNetwork', 'KiiThing', 'KiiThingContext', 'KiiThingQuery', 'KiiThingQueryResult', 'KiiThingWithToken', 'KiiTopic', 'KiiPushMessageBuilder', 'KiiTopicWithToken', 'KiiUser', 'KiiUserBuilder', 'KiiUserWithToken', 'KiiSocialNetworkName', 'KiiSite', 'KiiServerCodeEnvironmentVersion', '_KiiHttpRequestType', 'KiiACLAction', 'KiiAnalyticsSite', 'InvalidDisplayNameException', 'InvalidPasswordException', 'InvalidUsernameException', 'InvalidUserIdentifierException', 'InvalidEmailException', 'InvalidPhoneNumberException', 'InvalidLocalPhoneNumberException', 'InvalidCountryException', 'InvalidURIException', 'InvalidACLAction', 'InvalidACLSubject', 'InvalidACLGrant', 'InvalidLimitException', 'InvalidArgumentException', 'IllegalStateException', 'ArithmeticException', 'UnsupportedOperationException'],
    create: function() {
      return ctor.call(this);
    }
  };*/
  XMLHttpRequest = this.XMLHttpRequest;
  module.exports = ctor.call(this);
} else {
  ctor();
}
})();

6.コードにKiiのソースを追加
以下のような感じで使えるようになる。
import { Component } from '@angular/core';
import * as KiiCloud from 'kii-cloud-sdk';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title: string;
  id: string;
  password: string;
  result: string;

  constructor() {

    this.title = 'Kii Test';
      this.id = null;
      this.password = null;
      this.result = null;
      console.log(KiiCloud.KiiSite);
      console.log(KiiCloud.KiiSite.JP);
      this.result = KiiCloud.KiiSite.JP.toString();
  }

Angular2+でOnsenUIを使うまで

Angular2+でプロジェクトを作り、OnsenUIを使うまでの手順。
Node.JSはインストール済みの前提。

1.angular-cliをインストール
以下のコマンドを実行。
npm install -g @angular/cli


2.angularプロジェクトを作成
以下のコマンドを実行。
ng new my-app
cd my-app

3.OnsenUIを導入
以下のコマンドを実行。
npm install onsenui ngx-onsenui --save

4.OnsenModuleのインポート
"src\app\app.module.ts"にモジュールをインポートする記述を追加。
import { OnsenModule } from 'ngx-onsenui';

imports: [
   BrowserModule,
   OnsenModule,
],

5.CUSTOM_ELEMENTS_SCHEMA 読み込み
"src\app\app.module.ts"に"ons-" タグを書いても警告が出なくなる記述を追加
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

  schemas: [
      CUSTOM_ELEMENTS_SCHEMA,
  ],

6.CSSファイル読み込み
".angular-cli.json"にcss読み込みのコードを追記。
      "styles": [
        "../node_modules/onsenui/css/onsenui.css",
        "../node_modules/onsenui/css/onsen-css-components.css",
        "styles.css"
      ],

7.適当に編集して実行 以下のコマンドを実行。
ng serve --open


【参考】
AngularJS QuickStart
OnsenUI Angular 2+

2017年4月12日水曜日

Windows10向けPaSoRiを使用したFelicaアプリケーション開発の注意点

PaSoRiを使ってFelicaを読み込むWindows10向けアプリケーションを作ろうとしたら、ちょっとはまったのでメモ。


1.UWPアプリケーションだとfelicalib.dllが使えない
  ⇒全く同じソースでも、デスクトップアプリケーションはFelicaを検出できるが、UWPアプリケーションでは検出できない。

2.古いPaSoRi(RC-S370以下)ではPC/SCが使えない
  ⇒デバイスは認識するがFelicaを検出できない。Sony公式ソフトでTypeBには対応しているらしい。

2017年1月26日木曜日

【Angular2】カスタムディレクティブでの双方向データバインド

結論:できません



でも、イベントを使えばそれっぽいことができます。

■ディレクティブ
import {Component, EventEmitter} from '@angular/core';

@Component({
    selector: 'input-directive',
    inputs: ['inputValue'],
    outputs: ['inputEvent'],
    template: `<input [(ngModel)]="year" (change)="onYearChange($event) />`

export class YearListComponent {
    inputValue: string;
    inputEvent: EventEmitter = new EventEmitter();

    constructor(public manager: ServiceManager) {
    }

    //変更イベント
    public onChange(event) {
        this.inputEvent.emit(event);
    }
}
})


■ディレクティブを呼び出すHTML
<input-directive [inputValue]="data" (inputevent)="data=$event.target.value">
</input-directive>


2017年1月18日水曜日

【C#】行列番号からExcelのアドレスへの変換

【追記】
EPPlusにメソッドがあったのでそっちを使ったほうがらくちんです。
 OfficeOpenXml.ExcelAddress.GetAddress

タイトルそのまま、行番号、列番号を引数に渡してExcelのアドレス("A1"とか)に変換する処理。
そのまんまの処理なので特に開設はなしで。
コードをまとめるためにメソッド内でDictionaryのオブジェクトを作っていますが、使うときはいい感じのところで定義してください。

        /// 
        /// 行列番号をExcelのアドレス文字列に変換
        /// 
        /// 行番号
        /// 列番号
        /// 
        public static string ConvertExcelAddressString(int row, int col)
        {
            Dictionary DicInt2Alphabet = new Dictionary()
            {
                { 1, "A" },
                { 2, "B" },
                { 3, "C" },
                { 4, "D" },
                { 5, "E" },
                { 6, "F" },
                { 7, "G" },
                { 8, "H" },
                { 9, "I" },
                { 10, "J" },
                { 11, "K" },
                { 12, "L" },
                { 13, "M" },
                { 14, "N" },
                { 15, "O" },
                { 16, "P" },
                { 17, "Q" },
                { 18, "R" },
                { 19, "S" },
                { 20, "T" },
                { 21, "U" },
                { 22, "V" },
                { 23, "W" },
                { 24, "X" },
                { 25, "Y" },
                { 26, "Z" },
            };
            string address = "";
            int colTmp = col;

            //列番号がアルファベットの数よりも大きい場合(変換後AA以上となる場合) 2桁目の文字列を先に算出
            if(colTmp > DicInt2Alphabet.Count)
            {
                address = DicInt2Alphabet[col / DicInt2Alphabet.Count];
                colTmp = colTmp % DicInt2Alphabet.Count;
            }

            //行列番号を変換
            address += DicInt2Alphabet[colTmp] + row.ToString();

            return address;
        }

LINQ to Entitiesでの文字列大小比較

LINQではint.Parseが使えないので、文字列カラムを大小比較するにはCompareToメソッドを使用する。

例はstartDateが文字列で定義されているタコなDBからデータを抽出する場合。
しかも比較対象のパラメータがint型のため、事前にStringに変換する必要あり。
#LINQではtoStringメソッドが使用できないため

string startDate = this.param.startDate.toString();
var query =
    from ticket in _context.Tickets
    where ticket.StartDate.CompareTo(startDate) >= 0
    select ticket;

2017年1月12日木曜日

Angular2でBase64のExcelファイルをAjaxを使ってダウンロードする方法

■前提
・ExcelファイルはASP.NetのWebAPIで作成
 ⇒GETメソッドでxlsxファイルをResponseで返す

■ポイント
・responseTypeでArrayBufferを指定


this.http.get("http://hogehoge.com", { responseType: ResponseContentType.ArrayBuffer })
    .subscribe(
        data => {
            var blob = new Blob([data.arrayBuffer()], { type: data.headers.get("content-type") });
            var fName: string;
            fName = decodeURI(data.headers.get("content-disposition").substring(data.headers.get("content-disposition").indexOf('=') + 1));
            //IEの場合
            if (window.navigator.msSaveBlob) {
                window.navigator.msSaveOrOpenBlob(blob, fName);
            } else {
                //それ以外の場合(Chromeしか確認していない)
                var a = document.createElement('a');
                a.download = fName;
                a.target = '_blank';
                a.href = window.URL.createObjectURL(blob);
                a.click();
            }
        }
    )

2017年1月6日金曜日

WebAPIでEPPlusで作成したExcelブックをダウンロードする手順

ASP.NetでWebAPIを使ったサーバサイド処理にて、
EPPlusで作成したExcelブックをダウンロードさせる手順。
細かいところは省略してます。

public HttpResponseMessage Get([FromUri] SagyouNumKousuParamModelGet modelParam)
{
    //レスポンスインスタンス生成
    HttpResponseMessage response = this.Request.CreateResponse(HttpStatusCode.OK);

    using (ExcelPackage inputFile = new ExcelPackage(new System.IO.FileInfo(HttpContext.Current.Server.MapPath("./") + "assets\\Template.xlsx"), false))
    {
        //inputFileに対して色々と処理
        
        //Content作成
        response.Content = new ByteArrayContent(inputFile.GetAsByteArray());
        //Contentヘッダ設定
        response.Content.Headers.Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.Content.Headers.Add("content-disposition", "attachment;  filename=Sample.xlsx");
    }
}

EPPlusで名前付きセルの範囲を取得する

名前が定義されているのはNamesプロパティ。
シートに対する操作なので”ExcelWorksheet.Names["hogehoge"]”としてしまいがちだがこれではダメ。

名前はWorkbookで一意となるため、”ExcelWorkbook.Names["hogehoge"]”とする。


以下サンプル。
ExcelWorkbook workBook = inputFile.Workbook;
ExcelWorksheet template = inputFile.Workbook.Worksheets["Template"];
ExcelWorksheet workSheet = inputFile.Workbook.Worksheets.Add("Sheet1");

//名前「ヘッダ」の範囲をA1にコピー
workBook.Names["ヘッダ"].Copy(workSheet.Cells[1, 1]);