DataTableのあるレコードからDataGridViewのレコードを見つける〜ソートされたDataTable

  • 2017.08.30 Wednesday
  • 12:26

 

ずいぶん大昔に、DataGridViewの選択レコードからDataTableのレコードを見つけるという記事を書いたが、

今回はそれの逆、DataTableのあるレコードからDataGridView上の位置を見つける方法について考えてみる。

 

復習として、DataGridViewからDataTableの位置を見つけるには IndexOf を使えばその位置を取得できる。
 

   1:  Dim Index As Int32 = tbData.Rows.IndexOf(vwData(0).Row)


しかし、その逆はどうやらそう簡単ではなさそうだ。

 

 

というのも、DataGridViewのRowsはDataGridViewRowというクラスで、

これに対してIndexOfするためにはDataTableのDataRowをDataGridViewRowに変換してあげないといけない。

 

ザックリ書いてみると

 

   1:  Dim dgRow As DataGridViewRow = New DataGridViewRow
   2:  Dim intC As Int32
   3:   
   4:  dgRow.CreateCells(dgv)
   5:   
   6:  For intC = 0I To dgv.ColumnCount - 1I
   7:   
   8:      dgRow.Cells(intC).Value = tbData(intR).Item(intC)
   9:   
  10:  Next intC

 

といった感じで変換する方法があるようだ。

 

しかし、変換した DataGridViewRow でいざ IndexOf をしても、

-1、つまり一致しないと返ってくる

 

これは上のようなゴリッと書いたくらいの変換では完全にDataGridViewのRowと一致しないからである。

(どこが違うかはゴリゴリ書いて比較してみれば分かると思うので、省略)

 

ちなみに、適当な DataGridView 上の Rows を dgRow に突っ込んで IndexOf をするとちゃんとその行が取れるので、

上の変換にもうちょっと手を加えて完全に一致するような DataGridViewRow を作ってあげれば

今回の問題はクリアとなる。

 

ただ、IndexOf 自体が For ループで回しているのと同じ動作をしていることを考えると、

変な変換を書くより、単純に上から順に検索しても同じことと言えるので、

 

   1:  rwData = tbData(RowIndex)
   2:   
   3:  For intR = 0I To dgv.RowCount - 1I
   4:   
   5:      mrData = DirectCast(dgv.Rows(intR).DataBoundItem, DataRowView).Row
   6:   
   7:      If mrData.Equals(rwData) = True Then '一致した
   8:          Index = intR '一致した行
   9:          Exit For
  10:      End If
  11:   
  12:  Next intR

 

と DataGridView 上の DataRowView から DataRow を引っ張り出して、

DataTable 上の DataRow と比較して一致する場所を見つける方が単純かもしれない。

 

ちなみに、これなら簡単かなと思った方法、

DataGridViewと同じテーブルになる、DataTable.DefaultView.ToTable を生成して、

それに対して Rows.IndexOfしてみたが、

 

   1:  tbData = DirectCast(Me.DataSource, DataTable) 'テーブルを読み出す
   2:   
   3:  srData = tbData.DefaultView.ToTable 'DataViewからTableを読み出す
   4:   
   5:  Index = srData.Rows.IndexOf(rwData)

 

やはり -1 を返した。

もうひと工夫必要なのかもしれない

 

で、調べていると、DataView.Find というのがあるようで、

 

   1:  Index = tbData.DefaultView.Find(rwData.Item(ConIndex))

 

で 欲しい位置が取得できる。

 

注意として、というか今回の話の前提として、DataView.Sort でデータの並び替えをしていることが前提となる。

なので、Sort が Nullの場合エラーとなる。

 

Findは、並べ替え順序に基づいて行を検索しますが、

並べ替えが指定されていません。

 

ソートされていない場合、DataTable の位置と DataGridViewの位置は同じ(なはず)なので、

場合分けをして取り出すことで今回の問題が解決できる。

 

   1:  Dim tbData As DataTable = DirectCast(Me.DataSource, DataTable) 'テーブルを読み出す
   2:  Dim ojItem As Object
   3:   
   4:  If tbData.DefaultView.Sort <> "" Then 'ソートされている
   5:      ojItem = tbData.Rows(RowIndex).Item(FindIndex)
   6:      Index = tbData.DefaultView.Find(ojItem)
   7:  Else
   8:      Index = RowIndex 'そのまま返す
   9:  End If

 

 

 

 

関連投稿

DataGridViewの選択レコードからDataTableのレコードを見つける

DataViewのデータ(抽出結果)からDataTableの位置を検索

 

 

TypeScriptでLeafletを使ってみる・・・まで〜Visual Studio 2015

  • 2017.03.24 Friday
  • 23:26

 

さて、前回で終わりにしたが、

例えばjQueryなど、JavaScriptにしかないコードをTSに取り込むことはできるのか。

という話

 

ここ最近、黄色い電気ネズミゲームで良く目にするであろう地図でも使われているLeafletを

TypeScriptでも使えるのか調べて見たところ、

d.tsさえ取り込めば行けるような感じだったので、Visual Studioに組み込んでみることにした。

 

d.tsというのは、

簡単に言えば、C言語のヘッダファイルのようなものになる。

 

TSは型が定義された言語であるが、JavaScriptはそれがないので、

ソースをゴリゴリ書こうと思っても、型が不明と言われてしまう。

そこで、このd.tsというファイルで各変数やメソッドの型を定義してあげることで、

TSからJSの機能が使えるようになるわけである。

 

 

さて、下の記事によると、Leafletのd.tsを入れるには、npmコマンドを打つようである。

 

Making Map with Leaflet in TypeScript

 

なので、Visual Studioにnpmを組み込む必要があるので、

npmについて調べたところ、次の記事を見つけた。

 

最近のWebフロントエンド開発環境を Visual Studio 2015 (VS Code ではない)で構築する - npm パッケージインストール編 -

 

Visual Studioに Package Installer というものをインストールすれば良いらしい。

 

ツールの拡張機能と更新プログラムから

Package Installerで検索してインストール

で、記事の通り、Quick Install Packageでインストールしてみたのだが、

 

 

どうも、インストールされたような感じがしない。

 

どうやらソリューションファイルと同じ場所にインストールされてしまったようだ。

 

ということで、(自分の場合は)コマンドから打ち込んだ方が良いということで、

ツール→NuGetパッケージマネージャー→パッケージマネージャーコンソールを表示させて

 

 

npmコマンドを打ち込む。

※npm versionでインストールされているか確認できる

 インストールされているなら上のPackage Installerのインストールは不要

 入れてしまっていて、不要であればアンインストールか無効にすれば良い

 

 

っとその前に、dirコマンドで現在位置を確認すると、

 

やはりソリューションファイルの位置にいるようなので、

インストールするプロジェクトのフォルダにcdコマンドで移動して、

 

 

Leafletをインストール
 

 

インストールする場合は、leafletだけコマンドを打ち込んでも

勝手にgeojsonもインストールしてくれるのだが、

 

@types¥leafletの下に、node_modules¥@types¥geojsonという感じで置かれてしまうので、

 

 

やはり手順通り、geojsonを先にインストールして、

Leafletを続いてインストールした方が良いようである。

 

 

インストールしても変化がないようなら、すべてのファイルを表示で表示すると、

node_moduleフォルダ〜〜ができているはずである。

 

 

 

続いてソースを書く前に、これからゴリゴリ書くTSファイルの先頭に

referenceタグを追加して、

leafletとgeojsonのパスを通しておく。

 

/// <reference path="node_modules/@types/geojson/index.d.ts" />

/// <reference path="node_modules/@types/leaflet/index.d.ts" />

 

ちなみに、おまじないを書いておかないと警告が出る

 

 

 

あとはソースをゴリゴリ書くだけ・・・

 

 

表示できたので、Typescriptからでも扱えているようだ

 

 

 

あくまでd.tsファイルは型宣言や補完に使うだけで、

実際に動いているのはJSファイルのソースになるので、

間違いなく書けば動くのは当たり前である。

 

 

追記1

npmが全く無反応なので、ああ、いつものプロキシか・・・

ということで、設定。

 

プロキシの設定はこちらを参考にした

npm の proxy と registry 設定

 

自分のプロキシは上2行で問題なく通った。

追記2

コンパイルをするとLeafletのindex.d.ts上で、こんなエラー(TS1084)が出る。

 

TS1084 無効な reference ディレクティブ構文です。

 

仕様書に書いてあるreference タグのtypesによると、

 

'/// <reference types="..." />

 

という先ほど書いたpath="〜〜〜"ではなく、types="〜〜〜"に変えることで、

先ほどインストールされた@type以下を自動的に参照してくれるようで、

自分の環境の場合、これがうまく働いていないようで、エラーが出ているようだ。

 

考えてみるとVSのtsファイルは特にreferenceを宣言しなくても

VBやC#のように勝手に全ソースを見渡してくれるので、

コメントアウトして上書き保存して対処すればよい(?かもしれない)

 

追記3

d.tsのコンパイルミスか、VSのTypeScriptがエラーに厳しいのかは難しいところだが、

上のLeafletを入れるとこういったエラー(TS1110)が出る

 

 

TS1110 型が必要です。

 

どういう風に直せば良いのかが難しいが、

考えてみるとd.tsファイルはあくまで型宣言のないjsファイルに型を持たせてあげている定義ファイルなので、

自分がゴリゴリ書くソースで上でこのファイルから戻り値などは来ない訳である。

 

基本的に実行されるのは、tsファイルを変換したjsファイル

 

あくまで宣言が通れば良いとすれば、エラーの出ないような型に変更してあげれば良さそうである。

 

上の例だと、falseはboolean型なので、boolean

nullは、とりあえずany型としてあげたらコンパイルが通った。

 

よく分からないときはany型を使って逃げてしまうのもあり?

 

このやり方が正しい角かの判断は難しいところだが、

実際に動作するときには、index.d.tsは使用されないので、自分の中では解決と考えている。

 

※あくまでd.tsファイル上での修正なので、

 自身のソースコード上でのエラーであれば、 適切な型宣言を行ってください。

 

追記3

これまた上と同様に、d.ts変換時のミスと思われます。

 

?マークはオプション(引数を省略できる)の変数という意味で、

この場合の警告は、クラスメンバーを省略可能できないということなので、

?を消せば良いと思われる。

 

TS1112 クラスメンバーを省略可能として宣言することはできません。
 

※こちらもあくまでd.tsファイルの回避策なので、

 自身のソースコードでは正しい書き方で回避してください。

 

 

 

VB的に覚える TypeScript その8 〜 Visual Studio 2015

  • 2017.03.24 Friday
  • 23:13

 

前回 interface を説明できたので、

ようやく話を戻すことができる。

 

まず、Select [Combobox]を追加で配置する

[]内はVBのコントロール名

 

 

SelectにOptionをあらかじめ追加しても良いのだが、

今回はTSを使って追加することにする。

 

 

■VBのCombobox

いつも通り、VBで書いてみる。

こちらもソース上でItemを追加する。

まずは、HTMLのSelectと同じような感じにするため、構造体で次を作る。

(これをやりたかったので、前回構造体について説明した)

 

   1:  Private Structure Job
   2:   
   3:      Public Property Text As String
   4:   
   5:      Public Property Value As String
   6:   
   7:      Public Overrides Function ToString() As String
   8:   
   9:          Return _Text
  10:   
  11:      End Function
  12:   
  13:  End Structure

 

続いてLoadに次のソースを追加する。

 

   1:  Dim ojItem() As Object = New Object() {New Job() With {.Text = "会社員", .Value = "kaisha"},
   2:                                         New Job() With {.Text = "公務員", .Value = "koumu"},
   3:                                         New Job() With {.Text = "自営業", .Value = "jiei"},
   4:                                         New Job() With {.Text = "パート", .Value = "part"},
   5:                                         New Job() With {.Text = "学生", .Value = "student"}}
   6:  'Me.ComboBox1.Items.Clear() 'あらかじめItemが入っていた場合のリセット
   7:  Me.ComboBox1.Items.AddRange(ojItem)
   8:  Me.ComboBox1.SelectedIndex = 0I

 

1行目で追加するItemをObject型の配列で作って、

7行目でAddRangeでComboBoxのItemに追加

※AddRangeはObject型の配列なので、Job構造体をObjectに変換する必要がある。

 Job配列をObjectに変換しても良い。それについてはずいぶん前の記事参照

 

8行目で先頭を選択

 

実行すると

 

 

と追加される。

 

ちなみに、構造体の7行目でToStringメソッドを実装しているので

Comboboxのリストはその内容が表示される。

 

定義しないと構造体が表示されてしまう。

 

こちらもずいぶん前に書いた記事を参照

ListBoxやComboboxのDisplayMemberを考える〜VS2008

 

 

■TSでSelectに追加

さて、同じ感じでTSで書いてみる。

 

まずは構造体だが、前回書いた様にTSではVBでいう構造体はないので、

Interfaceでオブジェクトの定義型を作る。

 

   1:  namespace Job {
   2:      export interface Job {
   3:          Text: string;
   4:          Value: string;
   5:      }
   6:  }


これをonload時に先ほど作ったSelectに追加する

   1:  var fmSelect = <HTMLSelectElement>document.getElementById("Select1");
   2:  var fmOption: HTMLOptionElement;
   3:  var i: number;
   4:   
   5:  var ojItem: Job.Job[] = [{ Text: "会社員", Value: "kaisha" },
   6:                           { Text: "公務員", Value: "koumu" },
   7:                           { Text: "自営業", Value: "jiei" },
   8:                           { Text: "パート", Value: "part" },
   9:                           { Text: "学生", Value: "student" }];
  10:   
  11:  //fmSelect.innerHTML = ""; //あらかじめOptionが入っていた場合のリセット
  12:   
  13:  for (i = 0; i < ojItem.length; i++) {
  14:      fmOption = new Option();
  15:      fmOption.value = ojItem[i].Value;
  16:      fmOption.text = ojItem[i].Text;
  17:   
  18:      if (i === 0) 
  19:          fmOption.selected = true; //ここで選択           
  20:      
  21:      fmSelect.add(fmOption); //追加
  22:  }

 

VBに合わせるためにこんなソースになっているが、

TSはここまで複雑にする必要はないかもしれない。

 

とりあえず内容を見ていくと、

 

1行目でSelectを取得

5行目でVBのようにInterfaceを使ったオブジェクトの型定義をする。

13〜22行目でOptionを追加

 

まずはこんなところで、実行すると

 

 

わざわざinterfaceを組まなくても、

Optionを使って

 

   1:  var obItem: HTMLOptionElement[] = [new Option("会社員","kaisha" ,false,true ),
   2:                                     new Option("公務員","koumu" ),
   3:                                     new Option("自営業","jiei" ),
   4:                                     new Option("パート","part"),
   5:                                     new Option("学生", "student")];
   6:   
   7:  for (i = 0; i < obItem.length; i++) {
   8:      fmSelect.add(obItem[i]); //追加
   9:  }

 

とやった方が良さそうだ。

interfaceを使った方法はJSONなどからリストを読み込んだ場合などに使えそうなので、

どちらでもよさそうではある。

 

 

■ボタンに機能を追加する

さて、ここまで作ったらボタンに機能を付ける。

まずはVB

 

   1:  Dim slJob As Job = DirectCast(Me.ComboBox1.SelectedItem, Job)
   2:   
   3:  If txName <> "" Then
   4:      MessageBox.Show(String.Format("{0}さん {1}才 {2}", txName, nmAge, slJob.Text))
   5:  Else
   6:      MessageBox.Show(String.Format("ななしさん {0}才 {1}", nmAge, slJob.Text))
   7:  End If

 

選択されたComboboxのItemをキャストして、

メッセージ出力部を修正

 

 

HTMLのSelectに合わせて

Job構造体にValueを作ったが要らなかったようだ。

 

■TSのボタンに機能追加する。

VBをTSに翻訳する

   1:  var fmOption: HTMLOptionElement = <HTMLOptionElement>fmSelect.selectedOptions.item(0);
   2:  var txJob: string = fmOption.text;
   3:   
   4:  //省略
   5:   
   6:  if (txName !== "")
   7:      alert(`${txName} さん ${nmAge} 才 ${txJob}`);
   8:  else
   9:      alert(`ななしさん ${nmAge} 才 ${txJob}`);

 

valueを使おうかと思ったが、

こちらもVBをそのまま変換することができた。

 

実行すると

 

 

■せっかくなので

せっかくValueがあるので、

 

   1:  Dim txJob As String
   2:   
   3:  Select Case slJob.Value
   4:      Case "kaisha" : txJob = "会社員"
   5:      Case "koumu" : txJob = "公務員"
   6:      Case "jiei" : txJob = "自営業"
   7:      Case "part" : txJob = "パート"
   8:      Case "student" : txJob = "学生"
   9:      Case Else : txJob = "その他"
  10:  End Select

 

とValueから値を変換するコードを書いてみたりもできる。

 

TSなら

 

   1:  switch (fmOption.value) {
   2:      case "kaisha":
   3:          txJob = "会社員";
   4:          break;
   5:      case "koumu":
   6:          txJob = "公務員";
   7:          break;
   8:      case "jiei":
   9:          txJob = "自営業";
  10:          break;
  11:      case "part":
  12:          txJob = "パート";
  13:          break;
  14:      case "student":
  15:          txJob = "学生";
  16:          break;
  17:      default:
  18:          txJob = "その他";
  19:          break;
  20:  }

 

という感じになる。

 

さて、だいたい書きたいことは書いてきたので、

VB的に覚えるTypeScriptはこの辺でいったん投稿を終わりにする。

 

ざっと見てきても分かるように、

JavaScriptで考えるよりもVBなどからダイレクトに言語変換できるので、

JavaScriptをはじめようと考えているなら、

まずはTypeScriptから入ってみるのが早いかもしれない。

 

その後、コンパイルされて生成されたJavaScriptを眺めて

JavaScriptを勉強した方が、理解が早いのではと考える。

 

 

関連記事

VB的に覚える TypeScript その1 〜 Visual Studio 2015

VB的に覚える TypeScript その2 〜 Visual Studio 2015

VB的に覚える TypeScript その3 〜 Visual Studio 2015

VB的に覚える TypeScript その4 〜 Visual Studio 2015

VB的に覚える TypeScript その5 〜 Visual Studio 2015

VB的に覚える TypeScript その6 〜 Visual Studio 2015

 

 

HTMLアプリのデバッグができない?〜VS2015 + HTMLアプリケーション

XAMLデザイナーのデザインビューが表示されない?〜Visual Studio 2015

 

 

VB的に覚える TypeScript その7 〜 Visual Studio 2015

  • 2017.03.22 Wednesday
  • 21:52

 

クラスが出てきたので、構造体の話をしてみるが、

どうやらJSにそういったものがないので、TSにもないようだ。

 

いや、そもそも、VBやC#の構造体は、

参照型(クラス)か、値型(構造体)かの違いで、書き方などはほぼ同じもので、

前回書いたFruitクラスは Class を Structure に変更するだけで構造体にできる。

 

今回はTSの話なので、細かいところは他力ちゃんするが、

 

参照

クラスと構造体の使い分け

クラスまたは構造体の選択

 

VBでいうところの構造体は、TSではクラスで考えた方がよい。

 

 

では、構造体のようなものは本当に作れないのか

 

VB.netではなく、VB6やVBA、C言語の頃の構造体を思い出してみると、

値をまとめたモノを定義することはできた。

 

例えば、VB6やVBAなら Type を使って

 

   1:  Type Fruit
   2:    Name As String
   3:     Price As Integer
   4:  End Type

 

C言語なら struct を使って

 

   1:  struct Fruit{
   2:    char Name[256];
   3:     int  Price;
   4:  }

 

と書ける。

 

■TSで構造体(オブジェクトの型定義)

こういった形であれば、TSでも表現することができる。

 

   1:  namespace Yaoya {
   2:      export interface Fruit {
   3:          Name: string;
   4:          Price: number;
   5:      }
   6:  }

 

とinterfaceを使えばよい。

 

   1:  var newFruit: Yaoya.Fruit = { Name: "みかん", Price: 100 };
   2:   
   3:  alert(newFruit.Name + ":" + newFruit.Price);

 

 

ただし、実装している変数にもれなく値を入れる(初期化する)必要がある

 

 

ちなみに、インターフェイスの本来(?)の使い方は上のようなものではなく、

(上の使い方はオブジェクトの型定義などと言うようです)

 

例えば、長いことプログラムをゴリゴリ書いていると、

よく使う変数など、1つにまとめられるようなものが出てくると思う。

 

そういったものを1つにまとめた部品として、つまりinterfaceで定義しておくことで、

これから新たに作る際、生産性を上げることができる。

(間違いを少なくすることもできる)

 

クラスに似ているが、インターフェイスはあくまで定義が書かれただけのものになる。

 

逆に考えると、オブジェクトの型定義を1つの変数として値を渡すことができるので、

必ず必要なパラメータを渡したりするときは代入や取得のミスを少なくすることもできたりする。

 

細かいところは他力ちゃんします。

 

連載! とことん VB: 第 17 回 クラスの多重継承とその代替案

オブジェクトをつなぐためのインターフェイス

Typescriptのinterfaceの使い方

 

 

■interfaceを継承する

他力ちゃんですが、interfaceを継承したクラスを書いてみると

だいたいこんな感じになる。

 

   1:  namespace Yaoya {
   2:   
   3:      export interface IName {
   4:          Name: string;
   5:          Price: number;
   6:      }
   7:   
   8:      export interface ISanchi {
   9:          Sanchi: string;
  10:      }
  11:      
  12:      class Yasai implements IName {
  13:          Name: string;
  14:          Price: number;
  15:          Sendo: number;
  16:      }
  17:   
  18:      class Fruit implements IName, ISanchi {
  19:          Name: string;
  20:          Price: number;
  21:          Sanchi: string;
  22:   
  23:          private _Toudo: number;
  24:          
  25:          get Toudo(): number {
  26:              return this._Toudo;
  27:          }
  28:     
  29:          set Toudo(value: number) {
  30:              this._Toudo = value;
  31:          }
  32:      }
  33:  }
  34:   
  35:  namespace Sakanaya {
  36:      
  37:      interface ISendo {
  38:          Sendo: number;
  39:      }
  40:   
  41:      class Gyokai implements Yaoya.IName, Yaoya.ISanchi, ISendo {
  42:          Name: string;
  43:          Price: number;
  44:          Sanchi: string;
  45:          Sendo: number;
  46:      }    
  47:  }

 

interfaceをいくつか定義して、

Yasaiクラスのように継承したいinterfaceをimplementsで定義して書いてみたり、

 

Fruitクラスのように、複数のinterfaceを継承したり、

クラス独自の変数を定義したり、

 

namespaceでやおやとさかなやに別けて、

interfaceをexportすることで、別のnamespaceでも使用したりできる。

 

なお、interfaceは定義を継承する形となるので、

定義された変数やメソッドを実装していないと警告がでる。

 

 

 

継承できる点でクラスに似ているところはあるが、

何かを定義する(まとめる)というのは、

ある程度ゴリゴリ書いてからでないと、それをすることが難しいと思うので、

interfaceを継承する場面がどのくらいあるのか疑問である。

 

むしろinterfaceは上に書いたオブジェクトの型定義として使った方がよいかなと思う。

(ゴリゴリ書ける人はどんどん使った方がよいでしょう)

 

ザックリですがこんなところ。

 

 

関連記事

VB的に覚える TypeScript その1 〜 Visual Studio 2015

VB的に覚える TypeScript その2 〜 Visual Studio 2015

VB的に覚える TypeScript その3 〜 Visual Studio 2015

VB的に覚える TypeScript その4 〜 Visual Studio 2015

VB的に覚える TypeScript その5 〜 Visual Studio 2015

VB的に覚える TypeScript その6 〜 Visual Studio 2015

 

 

HTMLアプリのデバッグができない?〜VS2015 + HTMLアプリケーション

XAMLデザイナーのデザインビューが表示されない?〜Visual Studio 2015

 

VB的に覚える TypeScript その6 〜 Visual Studio 2015

  • 2017.03.12 Sunday
  • 22:58

 

前回はモジュールの話で終わってしまったので、

今回はクラスの話

 

■VBでクラスを書く

まずは、ここではよく使うfruitクラス(いつもは構造体ですが)をVBで書いてみる

 

   1:  Namespace Yaoya
   2:   
   3:      Public Class Fruit
   4:   
   5:          Private _Name As String
   6:          Private _Price As Integer
   7:   
   8:          Public Sub New(ByVal srcName As String, ByVal srcPrice As Integer)
   9:   
  10:              Me._Name = srcName
  11:              Me._Price = srcPrice
  12:   
  13:          End Sub
  14:   
  15:          Public ReadOnly Property Name() As String
  16:              Get
  17:                  Return Me._Name
  18:              End Get
  19:          End Property
  20:   
  21:          Public Property Price() As Integer
  22:              Set(value As Integer)
  23:                  Me._Price = value
  24:              End Set
  25:              Get
  26:                  Return Me._Price
  27:              End Get
  28:          End Property
  29:   
  30:          Public Overrides Function ToString() As String
  31:              Return Me._Name & ":" & Me._Price
  32:          End Function
  33:   
  34:      End Class
  35:   
  36:  End Namespace

 

せっかく前回Namespaseを書いたので、Namespase内でFruitクラスを定義してみた。

これを初期化(New)すれば使えるようになる。

 

   1:  Dim nwFruit As Yaoya.Fruit = New Yaoya.Fruit("みかん", 100)
   2:   
   3:  MessageBox.Show(nwFruit.ToString)

 

実行結果


余談になるが、VB2010以降であれば、かなり省略することができる。

 

   1:  Public Class Fruit
   2:   
   3:      Public ReadOnly Property Name As String
   4:      Public Property Price As Integer
   5:   
   6:      Public Sub New(ByVal srcName As String, ByVal srcPrice As Integer)
   7:   
   8:          Me.Name = srcName
   9:          Me.Price = srcPrice
  10:   
  11:      End Sub
  12:   
  13:      Public Overrides Function ToString() As String
  14:          Return Me.Name & ":" & Me.Price
  15:      End Function
  16:   
  17:  End Class

 

特にプロパティ内で処理がない場合はこの方がスッキリして見やすいであろう。

今回は次の話もあるので、最初の省略なしソースを使う。

 

 

■TSでクラスを書いてみる

さて、上のVBのクラスをTSで書いてみる

 

   1:  namespace Yaoya {
   2:   
   3:      export class Fruit {
   4:          private _Name: string;
   5:          private _Price: number;
   6:   
   7:          constructor(srcName: string, srcPrice: number) {
   8:              this._Name = srcName;
   9:              this._Price = srcPrice;
  10:          }
  11:   
  12:          get Name(): string {
  13:              return this._Name;
  14:          }
  15:   
  16:          get Price(): number {
  17:              return this._Price;
  18:          }
  19:   
  20:          set Price(value: number) {
  21:              this._Price = value;
  22:          }
  23:   
  24:          toString(): string {
  25:               return this._Name + ":" + this._Price;
  26:          }
  27:      }
  28:  }

 

だいたいこんな感じで、

こうやって、

 

   1:  var newFruit: Yaoya.Fruit = new Yaoya.Fruit("みかん", 100);
   2:   
   3:  alert(newFruit.toString());

 

実行結果

 

TSでもある程度の省略が可能である。

4〜10行目を

 

   1:  constructor(private _Name: string, private _Price: number) {
   2:  }

 

と置き換えることができる。

こちらもVBと合わせるために、省略なしの方を使う。

 

 

■コンストラクタ(New)と複数のコンストラクタ

クラスということで、コンストラクタ(VBはNew、TSはconstructor)をクラス内に定義する。

ちなみに、省略することも可能である。

 

逆に複数のコンストラクタを書いてみることもできるようだ。

 

例えば、VBで複数のコンストラクタを定義すると、

TSに変換するコードを意識しながら、

 

   1:  Public Sub New(ByVal srcName As String, ByVal srcPrice As Integer)
   2:   
   3:      Me.NewCore(srcName, srcPrice)
   4:   
   5:  End Sub
   6:   
   7:  Public Sub New(ByVal srcName As String)
   8:   
   9:      Me.NewCore(srcName, 0)
  10:   
  11:  End Sub
  12:   
  13:  Public Sub New(ByVal srcPrice As Integer)
  14:   
  15:      Me.NewCore("未定義", srcPrice)
  16:   
  17:  End Sub
  18:   
  19:  Private Sub NewCore(ByVal srcName As String, ByVal srcPrice As Integer)
  20:   
  21:      Me._Name = srcName
  22:      Me._Price = srcPrice
  23:   
  24:  End Sub

 

こんな感じに書いて、

そして、初期化してみると

 

   1:  nwFruit = New Yaoya.Fruit("みかん", 100)
   2:  MessageBox.Show(nwFruit.ToString)
   3:   
   4:  nwFruit = New Yaoya.Fruit("いちご")
   5:  nwFruit.Price = 300
   6:  MessageBox.Show(nwFruit.ToString)
   7:   
   8:  nwFruit = New Yaoya.Fruit(200)
   9:  MessageBox.Show(nwFruit.ToString)

 

実行結果

 

 

■TSの複数コンストラクタ

これをTSに書き直すと

 

   1:  constructor(srcName: string);
   2:  constructor(srcPrice: number);
   3:  constructor(srcName: string, srcPrice: number);
   4:  constructor(arg1: any, arg2?: any) {
   5:   
   6:      if (typeof arg1 === "string") {
   7:          this._Name = arg1.toString();
   8:          if (typeof arg2 === "number") {
   9:              this._Price = Number(arg2);
  10:          } else {
  11:              this._Price = 0;
  12:          }
  13:      }
  14:      else if (typeof arg1 === "number") {
  15:          this._Name = "未定義";
  16:          this._Price = Number(arg1);
  17:      }
  18:  }

 

ものすごく大ざっぱだが、こんな感じに書ける。

必要なコンストラクタを ; 区切りで定義して、

最後に、any型のコンストラクタを定義してあげることで、

複数のコンストラクタを作ることができるようだ。

 

ただ、前にも説明したように、any型で来るので、

それぞれの引数が、どのコンストラクタを通して初期化されたのかを

判別して変数に入れてあげる必要が出てくる。

 

自分の中だけで使う分には上のようなザックリでもよいが、

共有するためのクラスを作るなら判別はしっかりとしておいた方がよい。

 

さて、これを実行すると

 

 

何となく判別式を通っているようだ。

 

 

■?マークはOptional

説明が前後したが、arg2 の後ろに付いている?マークは、変数を省略可能であるという記号である。

VBで言うなら Optional となる。

 

   1:  Public Sub Hoge(ByVal arg1 As String, Optional ByVal arg2 As String = "hoge")
   2:  '処理
   3:  End Sub

 

VBのOptional は必ずデフォルト値が必要になるが、

同様にTSでもデフォルト値を設定できるようだが、

 

参考

TypeScript超入門(2):構文を理解する

 

TypeScriptを使用したHTMLアプリケーションではエラーが出てしまうようだ

 

パラメーターに疑問符および初期化子を指定することはできません。


とりあえず、デフォルト値は入れられないが、省略だけは可能であるので、

内部でNullかどうかという処理を入れる方がよい

 

 

■クラス内の変数を使うには

VBであれば、基本的にMeは省略できるが、

TSに書き換えをするときにだいたい同じ意味合いになるので、

今回は省略していない。

 

それとVBの話ですが、

継承などしたときに、継承基(MyBase)か継承先(Me)かを区別するのに、

書いておいた方が良いことがある。

 

さて、MeをTSに書き換えると、this になる。

こちらは省略できない。

 

Cannot find name xxx Did you mean the instance member this._Name ?

 

 

■プロパティ

VBのプロパティは、Property〜End Propertyを宣言して、

その中にget setアクセサを入れるが(上のソースで、Priceプロパティ)、

TSではProperty 〜 End Property はなく、

アクセサに、名前を付けて宣言する形となる。

 

また、VBのReadonly プロパティはgetアクセサだけ(上のソースで Name プロパティ)、

Writeonlyは set アクセサだけの宣言になる。

 

 

■メソッド

VBでメソッドを書く場合、

Sub や Function で定義して書くが、

 

TSのクラス内では、いきなりメソッド名から書く

ある意味 function を省略した形で書いているような感じと思えばよい。

 

 

■継承

上のFruitに追加機能を持たせた新しいクラスを作成することもできる。

まずは、VBの上のソースの一部を書き換えて

 

   1:  Protected _Name As String
   2:  Protected _Price As Integer

 

継承先で使わない場合は、privateのままで問題ありませんが、

もし使う場合はProtected にしておかないと警告がでます。

 

 

そして、継承クラスを作る。

 

   1:  Public Class FruitExt
   2:      Inherits Fruit
   3:   
   4:      Private _Sanchi As String
   5:   
   6:      Public Sub New(ByVal srcName As String, ByVal srcPrice As Integer, ByVal srcSanchi As String)
   7:   
   8:          MyBase.New(srcName, srcPrice)
   9:          Me._Sanchi = srcSanchi
  10:   
  11:      End Sub
  12:   
  13:      Public Property Sanchi As String
  14:          Set(value As String)
  15:              Me._Sanchi = value
  16:          End Set
  17:          Get
  18:              Return Me._Sanchi
  19:          End Get
  20:      End Property
  21:   
  22:      Public Overrides Function ToString() As String
  23:          Return MyBase._Name & ":" & MyBase._Price & ":" & Me._Sanchi
  24:      End Function
  25:   
  26:  End Class

 

ちょっと機能を追加した継承クラスを作ることができる。

 

これをTSに置き換える。

TSでも内部で使う場合は、

 

   1:  protected _Name: string;
   2:  protected _Price: number;

 

とprotected にする。

もちろん使わないならprivateのままでよい

 

あとは同じように書き換える

 

   1:  export class FruitEx extends Fruit {
   2:   
   3:      private _Sanchi: string;
   4:   
   5:      constructor(srcName: string, srcPrice: number, srcSanchi: string) {
   6:          super(srcName, srcPrice);
   7:          this._Sanchi = srcSanchi;
   8:      }
   9:   
  10:      get Sanchi(): string {
  11:          return this._Sanchi;
  12:      }
  13:      set Sanchi(value: string) {
  14:          this._Sanchi = value;
  15:      }
  16:   
  17:      toString(): string {
  18:          return this._Name + ":" + this._Price + ":" + this._Sanchi;
  19:      }
  20:  }

 

継承のおまじないは、VBの Inherits が、TSでは extends となる

 

VBの継承先のコンストラクタにある Mybase.New は、TSでは、super になる。

 

そして、基底の変数をMybase で呼び出したが、TSは this のままで良いようだ。

 

クラスはだいたいこんなところだろうか。

 

まだまだ話は続きます。


 

関連記事

VB的に覚える TypeScript その1 〜 Visual Studio 2015

VB的に覚える TypeScript その2 〜 Visual Studio 2015

VB的に覚える TypeScript その3 〜 Visual Studio 2015

VB的に覚える TypeScript その4 〜 Visual Studio 2015

VB的に覚える TypeScript その5 〜 Visual Studio 2015

 

HTMLアプリのデバッグができない?〜VS2015 + HTMLアプリケーション

XAMLデザイナーのデザインビューが表示されない?〜Visual Studio 2015

 

VB的に覚える TypeScript その5 〜 Visual Studio 2015

  • 2017.03.10 Friday
  • 23:49

 

さて、次の話をする前に、モジュールとかクラス、Namespaceなどの話を書いてみる

 

■VBのモジュール

VBをずっとゴリゴリ書いている人なら、

モジュール(module)という言葉は何となく分かると思う

 

   1:  Module Hoge
   2:      Private Function fcHoge() As String
   3:          Return "Hoge.fcHoge"
   4:      End Function
   5:   
   6:      Public Function exHoge() As String
   7:          Return "Hoge.exHoge"
   8:      End Function
   9:  End Module

 

こんな感じに書いて、

 

   1:  MessageBox.Show(Hoge.exHoge)

 

と呼ぶと、

 

 

ちなみに、VB.netは、VBの互換(?)としてモジュールが残っているような感じなので、

例えば、これからC#もやろうと思っている場合は、

モジュールというものはないので、

クラスでSharedな変数やメソッドを書くことになる。

いつもの他力ちゃんします。

 

連載! とことん VB: 第 14 回 Visual Basic 固有の「モジュール」(Module) の役割

 

 

■TSのモジュール

TSの場合もほぼ同じような感じである。

 

   1:  module Hoge {
   2:      function fcHoge():string {
   3:          return "Hoge.fcHoge";
   4:      }
   5:      export function exHoge(): string {
   6:          return "Hoge.exHoge";
   7:      }
   8:  }

 

こんな感じに書けて、

 

   1:  alert(Hoge.exHoge());

 

呼ぶと

 

 

■moduleはnamespace

ちなみに、TSでもmoduleで書くのは一昔前で、

最近の書き方としては、

 

   1:  namespace Hoge {
   2:      //コードを書く
   3:  }

 

といったように、module → namespace を使うのが良いらしい。

 

TSを勉強する中で、内部モジュールとか外部モジュールとかいう話が出てきて、

名前負けして挫折してしまう部分かもしれませんが、

 

内部module は namespace のことだよと言われるとちょっと分かってくる。

 

 

■外部モジュール

では、外部モジュールは?という話だが、

ちょっとVBではなく、VBAの方が感覚的に似ているので、

Excelのマクロで2つのモジュールを作って、それぞれにコードを書いて実行すると

 

 

ファイルをまたいで実行される。

 

TSの外部モジュールの考え方もこれと同じで、

新規にtsファイルを作って、

 

 

その中に、似たようなソースを書いて

 

 

今度は別のTSファイルから呼び出すと・・・

 

 

ちゃんと補完してくれる → ファイルをまたいで利用できるようだ。

もちろん実行すると、

 

 

ちゃんと出力される。

 

つまり、外部モジュール→別ファイルに書いたコードという感じであろう。

 

■外部モジュールの参照

ちなみに、今回はVSで「TypeScriptを使用したHTMLアプリケーション」を使っているが、

どうやらこのプロジェクトは、VBのプロジェクトのように、

次に書く、参照の手続きが要らないようだ。

 

しかし、その他の開発環境では必要になるので(そのうち書くが、jsファイルを取得する際はVSでも必要になる)、

忘れずに書いておく方がよい。

(不要ならコメントアウト)

 

まず、file1.ts を参照したい TSファイルのヘッダ(先頭行)に

スラッシュを3つ連ねて、続いて、reference タグを書き、

タグ内のpathに参照するTSファイルのパス(相対でよい)を入れる

 

   1:  /// <reference path="file1.ts" />

 

こんな感じ

 

 

このおまじないをすることで、先ほどのように補完してくれるようになると思う。

 

次に、これは「TypeScriptを使用したHTMLアプリケーション」でも必要になるが、

reference自体はTSだけのおまじないなので、コンパイルされるたJSでは参照はしてくれない。

 

なので、HTMLのソース内に

 

   1:  <script src="file1.js"></script>

 

と、jsファイルのパスを指定しておく必要がある。

もちろん読む順番は使う場所より前になるので、

 

 

という感じになる。

 

この手続きをすることで、先ほどの

 

 

が出力される。

 

■exportとimportとrequireによる参照

ちなみに、外部モジュールはexport、import、requireでも呼び出せるようなのだが、

ちょっと書いてみたのですが、「TypeScriptを使用したHTMLアプリケーション」ではうまくimportできなかった。

 

とりあえず、書き方として覚え書きしておく

referenceタグではなく、importを使ってファイルを指定する。

(ファイル名は拡張子なしでよい)

 

   1:  import hoge = require('./file1');

 

ただ、上のままのソースだと、

 

TS2306 ファイル *** はモジュールではありません。

 

と警告が出てしまう。

タイトルの通り、外部モジュールにexportが書かれていないからである。

 

file1.ts の中を次のように export 付きの namespace hoge を取り付けて、

さらに、内部の出力したいメソッドなどに export を付ける。

 

   1:  export namespace hoge {
   2:      function fcHoge(): string {
   3:          return "file1.fcHoge";
   4:      }
   5:      export function exHoge(): string {
   6:          return "file1.exHoge";
   7:      }
   8:  }

 

これで、警告が消えてくれるので、

先ほどの呼び出しを変更する。

 

   1:  alert(hoge.hoge.exHoge());

 

hogehogeばかりで分かりにくいが、

先頭のhogeがimportしたhoge

次の hoge が export した namespace のhoge

最後は export したメソッドになる。

 

これでうまく動いてくれれば良いのだが、

自分の「TypeScriptを使用したHTMLアプリケーション」では正しく動いてくれなかった。

 

プロジェクトのプロパティのビルド方法をAMDに変えてみたりしたが、

出力される結果は、それぞれのコンパイルの書式に変換はされているようだが、

やっぱりうまく動作しなかった。

 

 

もしかすると、他におまじないが足りないのかもしれない。
解決方法が分かれば追記したい。

 

とりあえず、ここでは(「TypeScriptを使用したHTMLアプリケーション」では)

referenceタグでの参照(または、省略)の方法で話をしていく。

 

その場合の file1.ts は namespace の export が取れて、

 

   1:  namespace hoge {
   2:      function fcHoge(): string {
   3:          return "file1.fcHoge";
   4:      }
   5:      export function exHoge(): string {
   6:          return "file1.exHoge";
   7:      }
   8:  }

 

となって、

 

   1:  alert(hoge.exHoge());

 

という感じで呼び出せる。

 

■export

さて、話をずいぶん飛ばしているが、

exportについて説明をしていなかった。

 

外部モジュールで書いた様に、namespace や class 内の変数やメソッドを

他の namespace 内のメソッドや class 内で使えるように出力するよ という意味になる。

 

なので、上の namespace hoge 内の export の付いていない fcHoge は別のとこからは参照することができない。

 

 

export が付いていないと private、付いていると public 見たいな感じになる。

 

ようやく一番最初のVBとTSのソースが同じような関係であると説明できた。

 

ところで、TSの module は namespace だよという話をしたが、

VBで Namespace に変更して書いてみると

 

 

怒られる。

VBではNamespace直下にメソッドはおけないので、

module や class を作って、その下に置く必要がある。

 

 

 

長くなったので、クラスは次回


 

関連記事

VB的に覚える TypeScript その1 〜 Visual Studio 2015

VB的に覚える TypeScript その2 〜 Visual Studio 2015

VB的に覚える TypeScript その3 〜 Visual Studio 2015

VB的に覚える TypeScript その4 〜 Visual Studio 2015

VB的に覚える TypeScript その5 〜 Visual Studio 2015

VB的に覚える TypeScript その6 〜 Visual Studio 2015

 

HTMLアプリのデバッグができない?〜VS2015 + HTMLアプリケーション

XAMLデザイナーのデザインビューが表示されない?〜Visual Studio 2015

 

 

リンクとして追加したら、うまく結合されない〜VB2015

  • 2017.03.10 Friday
  • 12:33

 

例えば、リリース用とデバッグ用にプロジェクトを別けたり、

別のプロジェクトとファイルを共有してソースを書いたりする際、

 

以前書いた、リンクとして追加という機能を使うのだが、

 

 

その際使ったのはVisual Studioの2008で、

久しぶりにこの機能を2015で使ってみたら・・・

 

 

バラバラ事件

 

どうやらフォームやサービスは、デザイナーやリソースがバラバラになってしまうようだ。

 

さて、どうしよう

 

ということで、プロジェクトファイル(vbproj)を眺めてみると、

 

 

どうやら、DependentUponというタグがミソらしい。

Designer.vb と resx ファイルに DependentUponタグを追加し、

結合したいメインのvbファイル名(ファイル名のみ、パスは不要)を入力したら

 

 

結合されました。

 

 

関連投稿

クラスやモジュールを共有したい〜VB2008

サービスプログラムのデバッグを考える〜VS2008 コンソールプログラムからのアプローチ

ASP.Netでサーバエラー〜文字コード化け

認識できるCSSプロパティ名ではありません〜Visual Studio 2015

  • 2017.03.09 Thursday
  • 23:13

 

ちょっとブレーク?

 

今回VS的TSでTypeScriptをゴリゴリ書いていたら、CSSで警告が出まくった。

 

検証(CSS 3.0): "xxx"は認識できるCSSプロパティ名ではありません。

 

ネットで調べたところ、Web Essential をインストールしたら出なくなったと書かれていたので、入れて見ることに。

 

Validation CSS 3.0 not a known property name

 

オンラインからWeb Essentialsを検索して、インストール

 

 

確かにエラーが消えてくれました。

 

別の方法で解決してみたかったが、良い方法が見つからなかったので、

解決法の一例まで

 

VB的に覚える TypeScript その4 〜 Visual Studio 2015

  • 2017.03.09 Thursday
  • 23:11

 

さて、次は数値を入力するInput(number) [NumericUpDown]を追加

[]内はVBのコントロール名

 

と思ったのだが、VS2015のツールボックスには用意されていないので、

とりあえずInput(text)を追加して、HTMLのソース上で、

 

   1:  type="number"

 

と変更しておく

 

 

numberタイプはブラウザによって表示が異なるようだが、

基本的にNumericUpDownのような数字の操作ができるようになるので、

textタイプとしておくより扱いやすい

 

ただ、後で解説するが、取得が文字列型になるので、

数値を取り出す場合は、条件式を入れておいた方がよい。

 

 

■数値ボックスをイベントに追加する

まずはVBでザックリこんな感じで書いてみて、

   1:  AddHandler Me.Button1.Click,
   2:      Sub()
   3:          Dim txName As String = Me.TextBox1.Text
   4:          Dim nmAge As Integer = Convert.ToInt32(Me.NumericUpDown1.Value)
   5:   
   6:          If txName <> "" Then
   7:              MessageBox.Show(String.Format("{0}さん {1}才", txName, nmAge))
   8:          Else
   9:              MessageBox.Show(String.Format("ななしさん {0}才", nmAge))
  10:          End If
  11:      End Sub

 

実行してみる

 

 

■VBのコードをTSで書いてみる・・・

さて、TSでこれを書いてみるのだが、

 

型 string を型 number に割り当てることはできません

 

そのままなにも考えずに書くと、

valueがstring型のため、number型に変換できないと怒られる。

キャスとしてみれば・・・と思ってやってみると、

 

型 string と型 number はどちらも互いに型に割り当てることができません。

 

■文字列→数値の変換について考える

数値の変換はいくつか関数が用意されていて、

 

   1:  nmAge = Number(fmAge.value);
   2:  nmAge = parseInt(fmAge.value);

 

などがある。

かなり強引なやり方で

 

   1:  nmAge = +fmAge.value;

 

符号を付けると変換されるというのもあるのだが、

仮に文字が入った場合なども考えるとお勧めはできない。

 

Number()やparseInt()の細かな仕様は他力ちゃんで、

 

こちらに載っているような正規表現を使って文字列を数値かどうか調べるか、

自分でゴリゴリ書くなら、

 

   1:  function isNumeric(value: any): boolean {
   2:      if (!value) 
   3:          return false;
   4:      else if (isNaN(value)) 
   5:          return false;
   6:      else if (typeof value === "string") {
   7:          if (value === "") 
   8:              return false;        
   9:          return true;
  10:      } else 
  11:          return false
  12:  }

 

といった感じのソースを書いて、

いろいろなデータを入れて見ると

 

   1:  var txNull: string;
   2:  var dtDate: Date = new Date(2017, 3-1, 1, 12, 23, 34);
   3:   
   4:  isNumeric(txNull);   //false : !value  : undefined
   5:  isNumeric(null) ;    //false : !value  : null
   6:  isNumeric("");       //false : !value  : ""
   7:  isNumeric(false);    //false : !value  : false
   8:  isNumeric(true);     //false : !string : true
   9:  isNumeric(dtDate);   //false : !string : Wed Mar 01 2017 12:23:34 GMT+0900 (東京 (標準時))
  10:  isNumeric("1a");     //false : isNaN   : 1a
  11:  isNumeric("blabla"); //false : isNaN   : aa
  12:  isNumeric("1");      //true  : number  : 1

 

何となく数字以外は弾いてくれる。

 

ただ、ここにも書いてあるように、isNaN関数は曖昧なところがあるようなので、

ブラウザによってこれで正しく通るかは不明なので、

先ほど書いた様な正規表現で検索する方が厳密かもしれない。

 

それと、!valueのところも、仮にvalueがnumber型の 0 の場合は引っかかってしまう(数値でないと判断される)ので、

後で出てくる型を調べる演算子(typeof)で判別してもよい

 

今回は文字列の判別が主なので、ザックリソースということで

 

 

■関数をどこに書くか

さて、先ほどのisNumeric関数はどこに書くかであるが、

 

VBの場合は、基本的にSubやFunction関数の外側に書くのが普通である。

というか、匿名関数のような使い方でない限り、たぶん書けない。

 

TSの場合も同じように、関数は関数の外に書くのが普通なので、

windoow.onloadより外側(1〜3行目)に書くのがよいと思う。

 

ただ、イベント処理をonloadの中に書いたのと同じように、

関数内に関数を書くこともできるが(6〜7行目の位置)、

その場合は、グローバルとかローカルとかいわゆるスコープの話になるが、

またその話になったら説明する、かもしれない。

とりあえず今回は、他力ちゃん

 

関数と関数スコープ

 

 

それと、VBは関数をどこに定義しても

勝手にその関数を探してくれるが、

TSでは怒られないようだが(?)、JSの厳密な構文チェックの場合、

C言語と同じように使う場所よりも先に定義しておかないと怒られてしまう(13〜15行目の位置)。

 

   1:  function isNumeric(){
   2:      //処理
   3:  }
   4:   
   5:  window.onload = () => {
   6:      function isNumeric(){ //ここにも書ける
   7:          //処理
   8:      }
   9:  };
  10:   
  11:  //VBのようにどこでも宣言できるが、
  12:  //厳密には使う位置より下には書かない方がよい
  13:  function isNumeric(){
  14:      //処理
  15:  }

 

 

■any型とTypeof演算子

続いて、引数 value に使っている型であるが、

VBのObject型のような型で、TSのany型を使った。

any型なので、文字列以外のすべての型に対応できる。

 

ただ、なんでもOKになってしまうので、

If文で振り分け処理を行って、今回の場合は、数値っぽい文字列を取り出している。

 

If文の途中に出てくる typeof というのは、VBでも

 

   1:  If TypeOf obj Is String Then
   2:  End If

 

といった感じで、変数の型を調べるのに使える演算子である。

 

 

■関数の型

そして、戻り値として、boolean型を指定している

変数と同じで、VBとだいたい似たような宣言になる。

 

   1:  Function isNumeric() As Boolean
   2:  End Function

 

   3:  function isNumeric(): boolean {
   4:  }

 

ちなみに、上は戻り値(この場合はboolean型)のあるFunctionになるが、

VBの戻り値がない関数、つまり、Sub関数はTSでは

 

   1:  function NoRetuen(): void {
   2:  }

 

という感じで、void型を宣言する。

 

■ようやくTSで書いてみる

 

話がだいぶそれてしまったが、TSでこれらをまとめて書いてみると

 

   1:  var fmTxt = <HTMLInputElement>document.getElementById("Text1");
   2:  var fmAge = <HTMLInputElement>document.getElementById("Numeric1");
   3:  var txName: string = fmTxt.value;
   4:  var nmAge: number; //= parseInt(fmAge.value);
   5:   
   6:  if (isNumeric(fmAge.value))
   7:      nmAge = Number(fmAge.value);
   8:  else
   9:      nmAge = 0;
  10:   
  11:  if (txName !== "")
  12:      alert(txName + "さん " + nmAge.toString() + "才");
  13:  else
  14:      alert("ななしさん" + nmAge.toString() + "才");

 

まずはこんな感じになる。

 

実行すると、

 

 

■文字列書式

さて、VBで文字書式のString.Formatメソッドを使って、

 

   1:  MessageBox.Show(String.Format("{0}さん {1}才", txName, nmAge))

 

と書いたが、TSにもそういった書式があるのかという疑問が出てくる。

検索すると一昔前まではそういった関数をゴリゴリ書く必要があったようですが、

最近のJSの仕様で、テンプレート文字列という機能ができたようなので、

それを使って書いてみると

 

   1:  if (txName !== "") {
   2:      alert(`${txName} さん ${nmAge.toString()} 才`);
   3:      //alert(txName + "さん " + nmAge.toString() + "才");
   4:  }
   5:  else {
   6:      alert(`ななしさん ${nmAge.toString()} 才`);
   7:      //alert("ななしさん" + nmAge.toString() + "才");
   8:  }

 

こんな風に書き換えることができる。

テンプレート文字列は、文字列で使う""や''で括るのではなく、 `` で囲むので注意したい。

` はバッククォート(グレイブアクセント)と読み、日本語キーボードなら Shift+@キー で入力できる。

余談だが、TSをコンパイルしたJSファイルを見ると

 

   1:  alert(txName + " さん " + nmAge.toString() + " 才");

 

と結局最初に書いた書式に戻されているので、

書きやすい方で書いた方が良さそうである。

 

■数値→文字列

せっかく数値に変換したが、出力は文字列で出したいので、

数値を文字列に変換。

 

文字列→数値への変換は手の込んだことをしたが、

逆の場合はVBでも使う、toStringを使えばOK。

ただ、忘れがちなのが、()を付けないといけない点。

これを忘れると、メソッドとして認識してくれない。

 

 

toStringに限らず、()忘れは気をつけたい。

 

ちなみに、VBでもそうだが、toStringは暗黙に解釈されるので、省略も可能である。

 

 

今回はこの辺で

 

 

関連記事

VB的に覚える TypeScript その1 〜 Visual Studio 2015

VB的に覚える TypeScript その2 〜 Visual Studio 2015

VB的に覚える TypeScript その3 〜 Visual Studio 2015

VB的に覚える TypeScript その4 〜 Visual Studio 2015

 

HTMLアプリのデバッグができない?〜VS2015 + HTMLアプリケーション

XAMLデザイナーのデザインビューが表示されない?〜Visual Studio 2015

 

VB的に覚える TypeScript その3 〜 Visual Studio 2015

  • 2017.03.09 Thursday
  • 23:02

 

さて、ボタンを追加したので、

次はテキストボックスを追加してみる。

 

Input(Text) [Textbox]を適当に配置

[]内はVBのコントロール名

 

 

 

■テキストボックスをイベントに追加する

前回のボタンイベントにこのテキストボックスを追加してみる。

 

まずはVBで書くと(一応TSのコードに合わせるように書きます)

 

   1:  AddHandler Me.Button1.Click,
   2:      Sub()
   3:          Dim txName As String = Me.TextBox1.Text
   4:   
   5:          If txName <> "" Then
   6:              MessageBox.Show(txName & "さん")
   7:          Else
   8:              MessageBox.Show("ななしさん")
   9:          End If
  10:      End Sub

 

動かすと、

 

 

ちなみに、TextboxがNullの場合は、If文で分岐しているので、

 

 

となる

 

■VBのコードをTSで書いてみる

これをTSで書くと
 

   1:  fmBtn.onclick = (e) => {
   2:      var fmTxt = <HTMLInputElement>document.getElementById("Text1");
   3:      var txName: string = fmTxt.value;
   4:   
   5:      if (txName !== "") {
   6:          alert(txName + "さん");
   7:      }
   8:      else {
   9:          alert("ななしさん");
  10:      }
  11:  };

 

これも動かしてみると

 

 

Nullなら

 

■VB と TSを比較してみる

■型宣言の省略

さて、ソースを比較していく

fmTxtは前回と同じように、TS内でテキストボックスを使えるように用意した変数。

型はHTMLInputElement型でキャスト

 

今回は :HTMLInputElement という型宣言はしなかったが、

VBでも、

 

 

といった感じで型を省略しても、自動で推測してくれる機能があり、

 

それと同じようにTSでも = で何かしらの型を入れると推測してくれる。

 

試しにマウスポインタをfmTxtにあててみると、

 

 

型を推測してくれていることが分かる。

なお、一度型を宣言すると、JavaScriptのように違う型の値を入れることはできないのがTSの特徴

 

 

■変数宣言

改めて型の宣言を確認してみる。

 

前回はいきなりHTMLElement型を使ったが、

なじみの深い文字列型 string型を使ってみる。

 

上がVB、下がTSの宣言

 

   VB:  Dim txName As String
   TS:  var txName: string;

 

前回も書いた様に、Dim が var 、As が : 、後は目的の型

それと、C言語同様にコードの終わりを示す ; (セミコロン) で変数を宣言できる

 

上でも説明したように、=を使えば、推測してくれる

 

   VB:  Dim txName = Me.TextBox1.Text
   TS:  var txName = fmTxt.value;

 

個人的な意見であるが、型は省略せずに宣言してあげた方が良いと思う。

 

その場に応じてソースを書けば良いとは思うが、

後で見返したとき(他の人が見たとき)に型が書いてあった方が、

パッと見たときに分かりやすいかなと思う。

 

ちなみに、= で初期化しない場合で型を宣言しないと、

 

Object型(VB)、any型(TS)とされてしまう。

 

そのため、都度キャストが必要となってしまい、処理速度や生産性の低下に繋がる。

 

 

■他の型

上でstring型を使ったが、TypeScriptの公式サイトから基本的な型を抜き出すとこんなのがある。

 

VB TS
 Boolean  boolean
 String  string
 Short  number
 Integer
 Long
 Float
 Double
 Decimal
 Object

 any

 Nothing

 null

 (undefine)

 

最近はTuple型とかNever型とかあるようですが、

TSのバージョンによっては使えない(VS2015は1.5〜1.8)ものもあるので、

今回はよく使う基本の基本なところだけ、

あとはまた出てきたら。

 

 

それと基本型以外で使いそうなところで、

 

VB TS
 Date  Date

 

とかもある。

 

追記

※TSのDateはDate型ではなく、Date interface であるため(VBも型と言うよりは構造体)、

 実際の型(typeofで取得される型)はobject型となる。

 interfaceを型のように判別するには、

 

   1:  toString.call(value);

 

 を使う方法があるようだ。

 (ただし、自作interfaceは難しいようだ)

 

参考URL

JavaScriptの「型」の判定について

 

 この場合、typeofでobjectとされたものでも、

 

 number  [object Number]
 string  [object String]
 boolean  [object Boolean]
 Array  [object Array]
 null  [object Null]
 自作  [object Object]

 

だいたいこのような感じに取得できる。

 

 

細かいことは仕様書に他力ちゃんで、話を進める。

(あくまでVB→TSが目的です)

 

 

■If文

続いて条件式のIf文

VBでは、

 

   1:  If 条件 Then
   2:      処理
   3:  Else
   4:      処理
   5:  End If

 

と If 〜 Then End If で構成される。

 

TypeScriptはC言語などと同じ書式で、

 

   1:  if (条件) {
   2:      処理
   3:  }
   4:  else {
   5:      処理
   6:  }

 

となる。

今回の様な alert関数 一文だけなら、{}を省略して、

 

   1:  if (条件)
   2:      処理;
   3:  else
   4:      処理;

 

ということもできるが、

入れ子になるようなIf文では、else if や else がどの If文にかかってくるのか判別しにくくなるので、

今回の様な短い文以外で省略はしない方が良いと思う。

とりあえず、省略するときは ; を忘れずに

 

追記

 

こんな感じの{}省略ソースを書いてみたところ、

 

最後のelseが手前のifと連動していることがポインタをあてると分かる。

 

極端な例ではあるが、こういった場合は、最後のelse if は{}で括って、

elseを外側のif文であると教えてあげる必要がある。

 

 

さて、If文で他の言語と違うのが、条件式の演算式

 

C言語同様に == や != で良いのだが、

最近のJSの書き方的には、型を厳密に判別するために、

=== や !== など等号を3つ連ねるのが良いらしい。

 

その辺はずいぶん前の記事で書いたので省略

 

型を厳密にという意味で、TypeScriptでは===を使った方がよさそうである。

 

VB TS
 =  ===
 <>  !==

 >

 >=

 >

 >=

 <

 <=

 <

 <=

 

■テキストの結合

ちょっと出力したいときのメッセージボックス(MessageBox.Show)は、

JSでも使われている alert で出力すればよい

 

1つ2つくらいならいいが、

何個もメッセージを出していると、OKを押すのが嫌になるので、

コンソール(イミディエイトウインドウ)に出力するなら

 

   VB:  Debug.WriteLine("hogehoge")
   TS:  console.log("hegehoge");

 

と書けば良い。

 

さて、テキストの結合であるが、VBでは & を使って(※)結合するが、

※昔のVB6やVBAからの人は文字列同士の結合は & 数字の加算は + と覚えているかと思うが、

VB.netでは、文字列も + で結合することができる。

 

   1:  txName & "さん"

 

TSはC#と同じように + を使って結合する。

 

   1:  txName + "さん"

 

 

それと、"" (ダブルクォーテーション) を '' (シングルクォーテーション)に変えて

括ってげても文字列として認識してくれます。

 

   1:  txName + 'さん'

 

この辺は書き方人それぞれという感じです。

 

今回はVB的に覚えると言うことで、TS側でも "" を使うことにしますが、

これまでJSでいろいろ書いてきた感じですと、

JSは '' で文字列を書くことの方が多いかもしれません。

 

たぶん、タグ内に使われる名称などが "" なので、スクリプト内でこれを表現するためには、

 

   1:  var txTag = '<input id="Button1" type="button" value="button" />';

 

という風に '' で書くことになるからだと思います。

(もし、"" で書いた場合は、¥" でエスケープする必要がある)

※¥は半角

 

 

だいたいこんな感じで今回はここまで

 

 

 

関連記事

VB的に覚える TypeScript その1 〜 Visual Studio 2015

VB的に覚える TypeScript その2 〜 Visual Studio 2015

VB的に覚える TypeScript その3 〜 Visual Studio 2015

VB的に覚える TypeScript その4 〜 Visual Studio 2015

 

HTMLアプリのデバッグができない?〜VS2015 + HTMLアプリケーション

XAMLデザイナーのデザインビューが表示されない?〜Visual Studio 2015

 

 

calendar

S M T W T F S
  12345
6789101112
13141516171819
20212223242526
2728293031  
<< May 2018 >>

search this site.

よく使う、検索される投稿

categories

アマゾン

楽天

selected entries

archives

recent comment

  • Thumbs.dbでフォルダが削除、名前の変更ができない件
    rockecco (05/18)
  • Thumbs.dbでフォルダが削除、名前の変更ができない件
    rockecco (05/18)
  • Thumbs.dbでフォルダが削除、名前の変更ができない件
    BWM (05/16)
  • Thumbs.dbでフォルダが削除、名前の変更ができない件
    通りすがり (05/09)
  • Windows Updateのサービスが起動していない
    rockecco (04/25)
  • Windows Updateのサービスが起動していない
    hiro (04/21)
  • Windows10 1607 のタスクスケジューラの挙動がおかしい?
    rockecco (03/27)
  • Windows10 1607 のタスクスケジューラの挙動がおかしい?
    Hiro (03/27)
  • 気象データを解く〜仕様書をダウンロードする
    rockecco (03/27)
  • 気象データを解く〜仕様書をダウンロードする
    TT (03/24)

recent trackback

profile


※当ブログはリンクフリーですが、 取材や雑誌等で掲載される場合は、事前にお知らせください

others

mobile

qrcode

powered

無料ブログ作成サービス JUGEM