Visual Studio 11 の販売宣伝が始まりました

ふと、MSDN から Windows XP をダウンロードしていたら(出先VMWareで開発環境を構築中、ホテルの回線が意外に太くて助かります。時に800K bytes 出ていたりするし)、Visual Studio 11 の宣伝がここに

Visual Studio 11 Beta:次期バージョンを買うなら、リリース前の今がお買い時
http://www.microsoft.com/japan/msdn/vstudio/save/

image

現在 msdn 等からダウンロードできるのは beta 版なので、「Visual Studio 11」が正式名称なのか、それとも「Visual Studio 2012」が正式名称になるのか(あるいは「Visual Studio 2013」とか、「新しい iPad」と同じく、「new Visual Studio」とか「Visual Studio」とだけ呼ぶとか。現在、「Visual Basic」というと「Visual Basic 6.0」のことではなくて、.NET Framework の Visual Basic を示すことになっているので、その手の改名はありかも)はわかりませんが、ひとまず、公式に購入宣伝が出てきたところを見ると、出てくるまでに1年はかからないかな、と思ったり。

現段階の事実として、Windows 8 の Metro style appliation は Windows 8 上の Visual Studio 11 beta でないと作れないので、実際の動作環境がそのままだとすると Windows 8 が出荷されてから、Visual Studio 11 が出荷という順番になります。けれども、Windows 8 に適した(特にタブレットPC、スレートPCに適した)形で Metro Strle のアプリケーションを提供する場合には、Visual Studio 11 が出荷された後に、Windows 8 が出荷されないといけないというジレンマがあります。現実的には、Beta 版なり Preview 版なりでビルドは可能なのですが、アプリケーションの製品を出荷する側(デベロッパーという意味で)側として、ちょっとあまり良くない状況かなと。Windows 8 と Visual Studio 11 が同時に出荷されてしまうのも困りもので。

Windows 8 customer preview 版を vmware に入れて色々といじって、Visual Studio 11 で WinForm, WPF, Metro style と三種類組んでみた比較としては、Metor style のアプリケーションを作る場合は、スレートPC を購入して実行環境/テスト環境として使うのがベターだろうと思っています。開発環境とテスト環境を別々にするのです。

  • 開発環境は、Windows 8 上のデスクトップスタイルの Visual Studio 11
  • テスト環境は、スレートPC に Windows 8 を入れて、タッチ等で動作確認

という具合です。開発用PCで Metro Style のアプリケーションをビルドすると、デプロイ(配置)も一緒に行われえるためにスタートページに非常に多くのアプリケーションが動くことになります。また、開発用PCでタッチパネルにするよりも、スレートPCを用意したほうが安いし動作させるときのスタイル(手に持って動かすとか)は実際に環境に近いでしょう。縦置きの液晶ディスプレイに腕を伸ばしてタッチするのは非常に苦痛です。ノートPCの場合は、ヒンジのところで問題がでそうだし。

Windows Phone の場合は、エミュレータで開発するわけですが、実はスレートPCの場合も解像度の関係からエミュレータ動作ができるといいんですどね。多分、VMWare を使って解像度を制限させれば似たようなことはできると思います。ただし、実機でタッチする感覚は iPhone アプリを試しに作ってみたときに気づいて、「実機でしかできない操作感を、アプリケーションのUIデザインにフィードバック」するには実機が必要ではないか、と思った次第で。

カテゴリー: 雑談 | Visual Studio 11 の販売宣伝が始まりました はコメントを受け付けていません

ロンドン橋落ちたの国で

逆光で暗くなってしまいましたが(カメラを持って来なかったので iPhone で)、ロンドン橋の近くにある場所で仕事で来ています。仕事で1週間ほど英語漬けになると、ちょっとはヒアリングがマシになるでしょうか…っほどの英語力しかないので、こころもとないかもしれませんが、宜しくお願いしますということで。

image

大学の頃に旅行したイタリアと同じく、ロンドンの街は古い建物が満載です。あたかも、シャーロックホームズの映画の中にいるように、その当時の建物が目の前にあります。地震がないのでできる技なのですが、建物自体の持久力は?ということと、中身をホテルやアパートに改造するときに、そのまま使うには不便ではないだろうか?と常々思っていたのですが、実は下の写真のように表の外壁だけを残して裏側全体を改築してしまうようです。

image

窓のところをよく見ると、裏が透けてみえます。出勤途中にざっと撮ったので分かりづらいのですが、表の煉瓦の部分だけを残して裏がごっそりありません。まるで映画のセットのようになっています。鉄骨で補強しながら作業をして、最終的には裏側に現代建築ができるというところでしょう。

日本ならば外壁を補修して中身を残すというところですが、イギリスの場合は外壁を残して中身を入れ替えるという感じなのですね。

地下鉄に乗って出勤をすると、まわりが濃いイギリス顔の方がいっぱい…というか当たり前なのですが、血の濃さを感じます。あと、サリーを付けているアラブ系(だったけ?)と黒人の方が意外と多いですね。黒人の方はパリッとしたスーツを着ていたり、中国人は無地の背広だったりします。

失業率だとか社会保障だとかを考えてロンドン橋のあたりを眺めていたりするのですが、日本の国がどうという話よりも、自分がどうしたいかを優先したほうがよいのでは?と思ったりします。一時期、没落であったり斜陽であったりの代表国であるイギリスですが、ロンドンの街並みと出勤途中に歩く人、古くからそのままの地下鉄、ごみを収集しているおじさん、公園でお昼を食べているカップルの群れ、なぜかやたらに走っている二階建てバスの群れ、工事現場のおじさん、パブにいる老夫婦、仕事の相手がフランス人と中国人と日本人だったりするのにイギリスに出張に来るという不思議さ、も含めて、中学生の頃に1ドルが300円近かった頃に米国に憧れる塾の先生を思い出して、1ドルを100円以下に押し上げて(押し下げて?)しまった経過は重要なのではないかな、と思い直したりします。

カテゴリー: 雑談 | 1件のコメント

逆引き大全iOSの脱稿間近

いや、間近というか、既に締切を過ぎておりますが、来月の末には発行の運びになる…という観測をば。

秀和システム様より、「逆引き大全 iPhone/iPad の極意 500(仮)」で出る予定です。

image

ネタ元をばらしておくと

Amazon.co.jp: iPhoneプログラミングUIKit詳解リファレンス: 所 友太, 京セラコミュニケーションシステム株式会社: 本

Amazon.co.jp: iPhone デベロッパーズ クックブック: Erica Sadun, 株式会社クイープ: 本

から相当パクリ…じゃなくて参考させて頂きました。なんせ、300 tips を執筆しないといけないので(共著の池谷さんが 200 tips で合計 500 ということで)、並みの数ではないッ!!! というのは毎度のことで、この2冊からピックアップして、Xcode 4.3.1 で作れるように直してあります。と云うのも、UIKit と デベロッパーズ クックブックは、実は api をそのまま呼び出して作っています。以前のタイプの iPhone プログラミングのコーディングの仕方を良く知らないので、何とも言えないのですが、

  • Interface Builder を使う方法
  • Interface Builder を使わない方法

の2種類があります。Visual Studio なんていう統合開発環境に慣れている(emacs も統合開発環境です、実は)場合は、当然 「Interface Builder を使う方法」を選択したほうが良い…ハズなんですが、mac の世界では微妙に違うようです。VC++ 6.0 の頃に画面をガシガシと Windows API のみで組んでいたような強者な方が mac なプログラマな方にはたくさんいらっしゃって、画面ひとつ作るにもコーディングだけで済ませてしまうという例題が多いのです。まあ、私もそれを狙ってこの二冊を買ったのですが。

で、去年の夏から調べていって、Xcode 3 -> Xcode 4 -> Xcode 4.2 -> Xcode 4.3 と来てしまった訳で、なんか非常に便利になっているのです。Xcode 4.3 がッ!!!(最新は、App Store で導入できる Xcode 4.3.1 です)

そんな訳で、生の iOS を使いつつ、できるだけ画面に近いところは Storyboard を使うという本の作りになっています。

 

image

Amazon.co.jp: これならわかる!iPhone/iPadアプリ開発入門講座―図解とサンプルでわかりやすい! Xcode4対応: 水口 克也: 本

こちらのほうは、同じく秀和システムから最近出たものです。

先に書いた通り、ちょっと前までの iOS プログラミング系はハードなものが多くて C言語をあらかじめ知っておかないと駄目という雰囲気があったのですが、最近はこの手の「やさしい」シリーズが出てきています。逆引きのほうで書いていて分かったのですが、iPhone プログラミングをしてみたいなぁと思ったときの躓きは、

  • まずは、開発環境をどうやって整えたらよいのか分からない。
  • 開発者登録をするらしいのだが、どうやったらいいのか?
  • アプリケーションを自分の iPhone で動かしたい場合はどうしたらいいのか?
  • アプリケーションを公開したいのだが、どうやったらいいのか?

ってのが問題になります。プログラミング自身よりも、導入そのもののがよくわからないというのと、アプリの公開というハードルをどうやってクリアするのか、に不安を感じます。まあ、実は1回やっていしまえばいいのですが、その初回が問題なんですよね。」

この本の場合、初っ端の導入と、最後の公開を抑えているので、本屋さんでぱらぱらと捲ってみると良いと思います。中身のアプリ開発な部分は…まぁ、初心者本なので、本当のプログラム初心者向きというところです。C言語の説明を抜いてしまって、アプリ開発に踏み込んだほうが良かったのでは、と思ったり。

まぁ、兎も角、初心者本と従来のハードな技術本を組み合わせて、google に検索を手伝って貰って、apple のサンプルをつらつらと動かしていくとなんとなくプログラミングができていきます。そのあたりの「手間」を手っ取り早く解決したいなぁ、というのが今回の逆引きの目的だったりします。ので、来月末ぐらいになったら、本屋なり amazon なり、秀和システムのホームページなりでどうぞ。

カテゴリー: Objective-C | 逆引き大全iOSの脱稿間近 はコメントを受け付けていません

花のズボラ飯に見る、手早くプログラミングを「済ます」というレシピ

Amazon.co.jp: 花のズボラ飯 うんま~いレシピ―なぜ、ズボラ料理なのに泣くほどうまいのか: 久住 昌之, 水沢 悦子: 本

2巻が出たばっかりですが、1巻を買おうと思ったのが、間違えて「レシピ」のほうを買ってしまうという…まぁ、昼は家にいることが多いので、しばらくはこれでご飯を作ってみますか。ええ、後から1巻は別の書店で買い直しました。

Amazon.co.jp: かっこいいスキヤキ (扶桑社文庫): 泉 昌之: 本 や、Amazon.co.jp: 豪快さんだっ! 完全版 (河出文庫): 泉 昌之: 本 を知っているので、内容的には外れはないのですが、ん~、絵を何故と思っていたものの、特に抵抗はなく機会があればと思ていた「ズボラ飯」です。「花」というのは名前だったのですね。旦那が単身赴任、本屋でバイトをする準一人暮らしの女性という設定は(主婦業なんだから、付いていっても良かろうと思うのですが)まあ、なかなかツボを得ています。わたくし的にツボと思うのは、

  • 旦那(ゴロさん)が絵的に出てこない。「既婚」という設定だけがある。
  • ひたすら、家でズボラ飯を作る(食べる)という回が続く。

清い、実に清い漫画です。この「清さ」は、久住/泉 昌之 しか出せません。口絵のところに、扇風機とコートとマフラーが一緒にでてくるところが、リアルです。あと、科白にいちいちダジャレを入れるのが、ストーリー性を無視した漫画という物語でありますね。

さて、「ズボラ飯」だけの解説だけで終わってしまってはつまらないので、プログラム関係に派生させてみます。

Amazon.co.jp: 職人学: 小関 智弘: 本 を読むと、「治具」(じぐ)という言葉がでてきます。製造業界で「部品を作るときの部品」というちょっとメタ的な使い方をするもので、直接製品には関わらないけれども、その部品を作成するときの支えとなるものです。この治具ですが、作成するのにあまり長時間掛かっては困ります。また、大量生産ができるものではない(少量多種の典型)なので、あまり複雑怪奇なものでは困ります。場合によっては、設計図自体はなくて製作者の勘や過去の経験(他の人の経験も含めて)を利用して作ります。(最近の、製造業界の治具は、非常に高度ですが)

これをプログラミングにあてはめてみると、

  • 本来、スクリプト言語(sh, awk, sed など)は使い捨てで作れるものが多かった。
  • 汎用性よりも、多様性を重視して、実行するのに直結するパターンが多い。
    (パラメータは、外部から与えるのではなく、ソースコード自身に書いてあるとか)
  • いちいちフローチャートなどを書くのではなく、さっくりと経験を踏まえて1日位で書いてしまう。

なところです。最近では、クラスライブラリなどが完備されてきたので、昔よりも非常に高機能なものができます。が、「さっくりと作れる」ところを忘れてしまうと、目的と手段を取り違えた「使い捨てプログラム」ができてしまうのが難点です。

で、「ズボラ飯」を読んでいて思ったのですが、

  • コンビニのおにぎりでお茶漬けを作るとか、
  • 鮭フレークを使うとか、
  • ふえるわかめが常備されているか、

そういう、コンビニエンスな加工食材が出てきます。この「コンビニ」なところというのは、いわゆるプログラム言語が持っている豊富なクラスライブラリにあたります(と強引に引っ張ってきます)。昔は、sh からちょこちょこと ls やら sed を組み合わせて作ったものですが、最近は C# で豊富なライブラリを駆使して作っても、「似たようなもの」が「似たような時間」で出来ます。このあたり、java や ruby のライブラリも同じですね。

となると、治具としては高機能すぎるのですが、実際に使っているものはほんのちょっぴり。かなりオーバースペックではあるものの、「既に」豊富なクラスライブラリがあるのですから(場合によっては無償で)、それを使えばプログラム的な「治具」が手軽に作れるわけです。このあたり、オープンソースに似ていますが、ちょっと違います。「無料」なところにポイントがあるのではなく、手近なところに手近な値段のものがある(コンビニで買うと、ちょっと高いけれどもコンビニエンスに、ちょっとだけ支払ってもよいですよね)というのがミソです。このあたり、apple appとかも同じです。

さて、「ズボラ飯」的にプログラミングをするとどうなるかというと、

  • 手元なり、手近なところに高機能なライブラリがある。
  • 高機能ではあるけれど、使うところは、ほんのちょっぴりで良い
    (マニュアルは、必要なところだけ読めばいい)
  • 過去の経験を踏まえて、さっくりと作る。
    ケチャップを入れるとか、味噌を入れるとか、結果を想像して調味料を入れるように、クラスライブラリの組み合わせにちょっとだけ手を加える。
  • そして、楽しみの彩(いろどり)を加える。
    ズボラ飯は、単に食するだけではなく、うまいズボラ飯を食う、という目的を達成する手段を持つ。

最後の「彩」のところは、プログラムで云えば、ちょっとアイコンを加えてみたり、デザインを変えてみたり、自分好みにスイッチを加えてみたり(他人には美味くなくてもよいのです)というところです。

で、何よりも「手軽」に作れるかつ、多少の手間を惜しまない(ミョウガを切るとか、海苔を細く切っておくとか)、の精神が必要ですね。

カテゴリー: 雑談 | 花のズボラ飯に見る、手早くプログラミングを「済ます」というレシピ はコメントを受け付けていません

Visual Studio の T4 を使って、ViewModel を自動生成してみる(多分途中)

常々、C# では C/C++ のようにマクロが使えん…と思っていたのですが、実は Visual Studio 2008/2010 上であれば、T4(TextTemplatingFilePreprocessor)を使ってマクロっぽい動きができる(=コードの自動生成ができる)ってことを今頃再確認して、ああ、なるほどと思って作ってみた次第です。

コード生成と T4 テキスト テンプレート
http://msdn.microsoft.com/ja-jp/library/bb126445.aspx
T4 TemplateでViewModelの生成をするアイテムテンプレートを作りました – かずきのBlog@Hatena
http://d.hatena.ne.jp/okazuki/20110325/1301070808
宣言的にクラスを宣言しT4 Templateでコードを生成する – かずきのBlog@Hatena
http://d.hatena.ne.jp/okazuki/20110408/1302275410

を参考にして、*.tt ファイルを作って、ViewModel を作ってみます。ViewModel クラスは、Silverlight + MVVM モデルで DataGrid をバインドの落とし穴(その2) | Moonmile Solutions Blog で書いていたときのパターンを使ってみます。チープすぎて実用的ではないのですが、T4 の自動生成の確認として。

宣言的にクラスを宣言しT4 Templateでコードを生成する – かずきのBlog@Hatena なところでは、設定ファイルを作っていますが、こちらでは、

/// <summary>
/// ViewModel クラス
/// </summary>
 [ViewModelTarget]
public class _ViewModel
{
	public int id { get; set; }
	public string name { get; set; }
	public int age { get; set; }
	public DateTime UpdateAt { get; set; }
}

な風に、クラスを定義しておけば勝手に INotifyPropertyChanged を継承した ViewModel クラスを作る、ってところを目指してみます。設定自体が生のクラスを使うってことろがミソです。

実は、テンプレートから自分のアセンブリを参照する方法が不明なので(もう少しトリッキーなことをやればできそうなんですが)、ViewModel を参照させるためだけのアセンブリを別に用意しています。

  • SampleT4 に、テンプレートがあります。
  • SampleT4Target は、アセンブリを参照するために用意しています。
  • SampleT4 から SampleT4Target をプロジェクト参照します。
  • _ViewModel.cs には、先の元になるクラスがはいっていて、2つのプロジェクトで共有(リンク)させています。

■ターゲットとなる ViewModel クラス

ちょっと無理矢理ですが、解析用のための MakeViewModel クラスを作成しています。
属性「ViewModelTarget」が付いているクラスを探すのですが、_ViewModel.cs 自体が共有されているので、無理矢理、文字列で属性値を調べています。

namespace SampleT4Target
{
	/// <summary>
	/// ViewModel クラス
	/// </summary>
	[ViewModelTarget]
	public class _ViewModel
	{
		public int id { get; set; }
		public string name { get; set; }
		public int age { get; set; }
		public DateTime UpdateAt { get; set; }
	}

	public class MakeViewModel
	{
		public string className;
		public List<Prop> props;
		public MakeViewModel( Type c )
		{
			this.className = c.Name;
			this.props = new List<Prop>();
			foreach (var p in c.GetProperties())
			{
				props.Add(new Prop { name = p.Name, type = p.PropertyType });
			}
		}
		public class Prop
		{
			public string name { get; set; }
			public Type type { get; set; }
		}
		public static List<Type> TargetTypes(string fname = "")
		{
			var lst = new List<Type>();

			Assembly asm = (fname == "")?
				Assembly.GetExecutingAssembly():
				Assembly.LoadFile(fname);

			foreach (var t in asm.GetTypes())
			{
				foreach (var at in t.GetCustomAttributes(false))
				{
					if ( at.GetType().ToString().IndexOf("ViewModelTarget") >= 0 ) 
					// var attr = at as ViewModelTargetAttribute;
					// if (attr != null)
					{
						lst.Add(t);
					}
				}
			}
			
			return lst;
		}
	}
	public class ViewModelTargetAttribute : Attribute
	{
	}
}

■ViewModel のテンプレート

テンプレートファイル「ViewModel.tt」は、以下のようになります。
アセンブリを直接参照させているので、ここが嫌なんですが(プロジェクト名が変わると変更しないといけないので)ひとまず、これでコンパイルが通ります。

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="$(SolutionDir)\SampleT4Target\bin\Debug\SampleT4Target.dll" #>
<#@ import namespace="SampleT4Target" #>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace SampleT4
{
<#
var types = MakeViewModel.TargetTypes();
foreach (var t in types) {
	var mk = new MakeViewModel(t);
#>
	/// <summary>
	/// <#= mk.className #> クラス
	/// </summary>
	public class <#= mk.className #> : INotifyPropertyChanged
	{
<# foreach ( var p in mk.props ) { #>
		private <#= p.type.ToString() #> _<#= p.name #>;
		public <#= p.type.ToString() #> <#= p.name #>
		{
			get { return _<#= p.name #>; }
			set
			{
				if (_<#= p.name #> != value)
				{
					_<#= p.name #> = value;
					OnPropertyChanged("<#= p.name #>");
				}
			}
		}
<# } #>
		#region INotifyPropertyChanged メンバ
		/// <summary>
		/// プロパティ変更時のイベント
		/// </summary>
		public event PropertyChangedEventHandler PropertyChanged;
		protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
		{
			if (PropertyChanged != null)
				PropertyChanged(this, e);
		}
		protected virtual void OnPropertyChanged(string name)
		{
			if (PropertyChanged != null)
				PropertyChanged(this, new PropertyChangedEventArgs(name));
		}
		#endregion
	}
<# } #>
}

テンプレートの中身自体は、インテリセンスが効かない状態なので(T4用の拡張プラグインを入れると効きます)、一度 *.cs ファイルに書き出してからちまちまと移しています。PHP か ASP.NET 風に書けば ok です。

Devart T4 Editor for Visual Studio 2010 sample
http://visualstudiogallery.msdn.microsoft.com/a42a8538-8d6e-491b-8097-5a8a00174d37
でダウンロードができます。

■自動生成された ViewModel.cs

テンプレートを保存すると、T4(TextTemplatingFileGenerator)が実行されて、ViewModel.cs ファイルが作成されます。本来は、partial にしてカスタマイズ部分と分離させると良いかなと。クラス名が元ネタのクラスと同じなので、実際は何らかのルールで変えたほうがよいでしょう。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace SampleT4
{
	/// <summary>
	/// _ViewModel クラス
	/// </summary>
	public class _ViewModel : INotifyPropertyChanged
	{
		private System.Int32 _id;
		public System.Int32 id
		{
			get { return _id; }
			set
			{
				if (_id != value)
				{
					_id = value;
					OnPropertyChanged("id");
				}
			}
		}
		private System.String _name;
		public System.String name
		{
			get { return _name; }
			set
			{
				if (_name != value)
				{
					_name = value;
					OnPropertyChanged("name");
				}
			}
		}
		private System.Int32 _age;
		public System.Int32 age
		{
			get { return _age; }
			set
			{
				if (_age != value)
				{
					_age = value;
					OnPropertyChanged("age");
				}
			}
		}
		private System.DateTime _UpdateAt;
		public System.DateTime UpdateAt
		{
			get { return _UpdateAt; }
			set
			{
				if (_UpdateAt != value)
				{
					_UpdateAt = value;
					OnPropertyChanged("UpdateAt");
				}
			}
		}
		#region INotifyPropertyChanged メンバ
		/// <summary>
		/// プロパティ変更時のイベント
		/// </summary>
		public event PropertyChangedEventHandler PropertyChanged;
		protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
		{
			if (PropertyChanged != null)
				PropertyChanged(this, e);
		}
		protected virtual void OnPropertyChanged(string name)
		{
			if (PropertyChanged != null)
				PropertyChanged(this, new PropertyChangedEventArgs(name));
		}
		#endregion
	}
}

と、ここまで生成ができます。

本当は、別プロジェクトを作るのではなくて自前のアセンブリを参照して、対象の ViewModel クラスを見つけたいですよね。一度、「ViewModelTarget」の属性がない状態でビルドをした後に、別のところに保存。それを一時的に参照させればよいかな、と考えていますが。

カテゴリー: C# | Visual Studio の T4 を使って、ViewModel を自動生成してみる(多分途中) はコメントを受け付けていません

[C#] パイプで繋げて、データベースを検索

ふと、|演算子(パイプ演算子)を使って、データベースのストリームを検索できたら、何かできるのではなかろうか…と骨休めがてらちょっと。

public class Test
{
	public void test001()
	{
		var db = new DB{ ConnectionString=""};
		RESULT items = db | "person" |
			"familyname".EQ("masuda") |
			"age".GE(20) |
			"*";
		RESULT items2 = db | "person" |
			"familyname".EQ("masuda") |
			"age".GE(20) |
			"id" | "familyname" | "lastname";
	}
	public void test002()
	{
		var db = new DB { ConnectionString = "" };
		RESULT items = 
			db | "person" |
			(EQ)"familyname" % "masuda" |	// familyname == "masuda" と同じ
			(UP)"age" % 20 |				// age >= 20 と同じ
			"*";
	}
	public void test003()
	{
		// これが直感的で良い
		var db = new DB { ConnectionString = "" };
		RESULT items =
			db | "person" |					// テーブルを指定
			(OP)"familyname" == "masuda" |	// 検索条件
			(OP)"age" >= 20 |				
			"*";							// 出力
	}
}

データストリームというよりも、擬似LINQ構文になっちゃった感じで、あまり意味がありませんが。|演算子のオーバーライドと、暗黙の型変換(implicit)を駆使すると、こんな風に書けますという例です。
データの比較を行うときに、”カラム名”.EQ(値) のように、最初はメソッド名を考えてみたのですが、あまり可読性がよくないので、「==演算子」等もオーバーライドすることにしました。

OP クラスのところが肝で、テーブルのカラム名(文字列)を一度 OP クラスにキャストしてから使うという妙な技をつかっています。このあたりは、もう少ししっかりと作れば、LINQ と同じになるんでしょうが、しっかり作ってしまうと LINQ と同じになりそうなんで、このあたりで止めておきます。

上記のコードをコンパイルするためのクラス群は以下になります。コンパイルするためだけなので、中身は作っていませんが、まあ、構造が分かるかと。本来はパイプで使うわけだから、グラフィック系のフィルターのようにしたいですよね。ちょっとそのあたりの例は思案中ということで。

public class DB
{
	private SqlConnection _cn;
	public string ConnectionString { get; set; }
	public static DB operator |(DB db, string name)
	{
		return db;
	}
	public static DB operator |(DB db, OP op)
	{
		return db;
	}
	public static implicit operator RESULT(DB db)
	{
		return new RESULT();
	}
}

public static class DPipeExtentions
{
	public static OP EQ( this string cname, object val )
	{
		return new OP { ColumnName = cname, Value= val, OpCode = OP.OPRATOR.EQ };
	}
	public static OP NE( this string cname, object val )
	{
		return new OP { ColumnName = cname, Value= val, OpCode = OP.OPRATOR.NE };
	}
	public static OP LE(this string cname, object val)
	{
		return new OP { ColumnName = cname, Value = val, OpCode = OP.OPRATOR.LE };
	}
	public static OP LT(this string cname, object val)
	{
		return new OP { ColumnName = cname, Value = val, OpCode = OP.OPRATOR.LT };
	}
	public static OP GE(this string cname, object val)
	{
		return new OP { ColumnName = cname, Value = val, OpCode = OP.OPRATOR.GE };
	}
	public static OP GT(this string cname, object val)
	{
		return new OP { ColumnName = cname, Value = val, OpCode = OP.OPRATOR.GT };
	}
}
public class OP
{
	public enum OPRATOR {
		EQ, NE, LT, LE, GT,GE,
	}
	public OPRATOR OpCode { get; set; }
	public string ColumnName { get; set; }
	public object Value { get; set; }
	public static OP operator %(OP op, object val)
	{
		op.Value = val;
		return op;
	}
	public static implicit operator OP(string name ) {
		return new OP{ ColumnName = name };
	}
	public static OP operator ==(OP op, object val) { 
		return new OP { ColumnName = op.ColumnName, Value = val, OpCode = OPRATOR.EQ };
	}
	public static OP operator !=(OP op, object val)
	{
		return new OP { ColumnName = op.ColumnName, Value = val, OpCode = OPRATOR.NE };
	}
	public static OP operator <(OP op, object val)
	{
		return new OP { ColumnName = op.ColumnName, Value = val, OpCode = OPRATOR.LT };
	}
	public static OP operator <=(OP op, object val)
	{
		return new OP { ColumnName = op.ColumnName, Value = val, OpCode = OPRATOR.LE };
	}
	public static OP operator >(OP op, object val)
	{
		return new OP { ColumnName = op.ColumnName, Value = val, OpCode = OPRATOR.GT };
	}
	public static OP operator >=(OP op, object val)
	{
		return new OP { ColumnName = op.ColumnName, Value = val, OpCode = OPRATOR.GE };
	}
	public override bool Equals(object obj)
	{
		return base.Equals(obj);
	}
	public override int GetHashCode()
	{
		return base.GetHashCode();
	}
}
public class RESULT : List<object>
{
}
public class EQ : OP
{
	public static implicit operator EQ(string name)
	{
		return (EQ)new OP { ColumnName = name, OpCode = OPRATOR.EQ };
	}
}
public class UP : OP
{
	public static implicit operator UP(string name)
	{
		return (UP)new OP { ColumnName = name, OpCode = OPRATOR.GE };
	}
}
カテゴリー: C# | [C#] パイプで繋げて、データベースを検索 はコメントを受け付けていません

Excel VBA で jQuery のようにアクセスできるライブラリを作れるか?

ちっとばかり頭の体操の意味も込めて、Excel VBA を jQuery 風に弄れるかどうかのテストを。結論から言えば、結構いけます。行けるんじゃないだろうか?の段階まではできました。

Option Explicit

' 宣言
Private XL As New XLQuery

Sub test001()
    XL.Cell("A1").Text = "masuda"
    XL.Cell("A1:A10").Text = "masuda"
    ' 行列指定
    XL.Cell(1, 2).Text = "masuda"
    ' 範囲指定
    XL.Cell(1, 2, 10, 2).Text = "masuda"
    ' 名前定義
    XL.Cell("#name").Text = "masuda"
    ' クラス定義(実は名前)
    XL.Cell(".name2").Text = "masuda"
End Sub

Sub test002()
    ' 背景色を設定
    XL.Cell(1, 1).css("background-color") = "#FF0000"
    ' 文字色を設定
    XL.Cell("A2").css("color") = "blue"
End Sub

な風なコードを書くと、

な位まではできることが確認できました。

練習コードも含めてあるので、無駄が多いですが、ちょっと全コードを晒しておきますw 二つのクラス(XLQuery, XLRange)を作ってください。

XLQuery クラス

Option Explicit
''' excel vba query

Private EmptyBook_ As Workbook
Private EmptySheet_ As Worksheet
Private Current_ As Worksheet
Private Selection_ As Range

''' 簡易プロパティ
Public Property Get Application() As Excel.Application
    Applicaiton = Excel.Application
End Property
Public Property Get Book() As Workbook
    Set Book = Excel.ActiveWorkbook
End Property
Public Property Get Sheet() As Worksheet
    Set Sheet = Excel.ActiveSheet
End Property

''' コンストラクタ
Public Sub Class_Initialize()
    Set Current_ = Excel.ActiveSheet
    Set Selection_ = Excel.ActiveSheet.Cells(1, 1)
End Sub

''' Empty チェック
Public Property Get EmptySheet() As Worksheet
    Set EmptySheet = EmptySheet_
End Property
Public Function IsEmptySheet(sh As Worksheet) As Boolean
   Set IsEmptySheet = IIf(sh = EmptySheet_, True, False)
End Function

''' Worksheet を取得
Public Function GetSheet(name As String) As Worksheet
    Set GetSheet = EmptySheet_
    Dim sh As Worksheet
    For Each sh In Me.Book.Sheets
        If sh.name = name Then
            Set GetSheet = sh
            Exit For
        End If
    Next
End Function

''' カレントシートの設定/取得
Public Property Get Current() As Worksheet
    If Current_ Is Nothing Then
        Set Current = EmptySheet_
    Else
        Set Current = Current_
    End If
End Property
Public Property Let Current(v As Worksheet)
    If v Is EmptySheet Then v = Nothing
    Set Current_ = v
End Property

''' テキストを取得/設定
Public Property Get Text() As String
    If Selection_ Is Nothing Then
        Text = ""
    ElseIf Selection_ Is Range Then
        Dim rg As Range
        Set rg = Selection_
        Text = rg.Text

    Else
        Text = ""
    End If
End Property
Public Property Let Text(Value As String)
    If Not Selection_ Is Nothing Then
        If TypeOf Selection_ Is Range Then
            Selection_.Value = Value
        End If
    End If
End Property

''' セルにアクセス
Public Function Cell(r1 As String, Optional c1 As String = "", Optional r2 As String = "", Optional c2 As String = "") As XLRange
    Dim rg As New XLRange
    ' Cell("A1")呼出
    ' Cell("A1:B10")呼出
    ' Cell("#id")呼出
    ' Cell(".class")呼出
    If c1 = "" Then
        If Left(r1, 1) = "#" Then
            rg.self = Me.Sheet.Range(Mid(r1, 2))
        ElseIf Left(r1, 1) = "." Then
            rg.self = Me.Sheet.Range(Mid(r1, 2))
        Else
             rg.self = Me.Sheet.Range(r1)
        End If
    ' Cell(1,1)呼出
    ElseIf r2 = "" Then
        rg.self = Me.Sheet.Cells(CInt(r1), CInt(c1))
    ' Cell(1,1,2,10)呼出
    Else
        rg.self = Me.Sheet.Range(Me.Sheet.Cells(CInt(r1), CInt(c1)), Me.Sheet.Cells(CInt(r2), CInt(c2)))
    End If
    Set Cell = rg
End Function

XLRange クラス

Option Explicit
Private text_ As String
Private range_ As Range

Public Property Get Text() As String
    Text = text_
End Property
Public Property Let Text(v As String)
    text_ = v
    If Me.self Is Nothing Then Exit Property
    Me.self.Value = v
End Property

Public Property Get self() As Range
    Set self = range_
End Property
Public Property Let self(v As Range)
    Set range_ = v
End Property

Public Property Let css(prop As String, v As String)
    If Me.self Is Nothing Then Exit Property
    Select Case StrConv(prop, vbLowerCase)
    Case "background-color": self.Interior.Color = toRGB(v)
    Case "color": self.Font.Color = toRGB(v)
    End Select
End Property

Private Function toRGB(v As String)
    If Left(v, 1) = "#" Then
        Dim r, g, b
        r = CInt("&H" + Mid(v, 2, 2))
        g = CInt("&H" + Mid(v, 4, 2))
        b = CInt("&H" + Mid(v, 6, 2))
        toRGB = RGB(r, g, b)
    Else
        Select Case v
        Case "red": toRGB = RGB(255, 0, 0)
        Case "blue": toRGB = RGB(0, 0, 255)
        Case "green": toRGB = RGB(0, 255, 0)
		' このあたりは後で
        End Select
    End If
End Function

プロパティとパラメータの省略(option)を駆使して、それ風に動くようにします。VBA の制限としてクラスをひとつのファイルに複数のクラスを置けないので、利用する側を考慮してクラスは多くない様にします。なので、継承など本来のオブジェクト指向は無視して(苦笑)、使いやすい形で「オブジェクト」の部分だけ残しておくということで。
XLRange クラスの css プロパティを使って、スタイルシート風に設定ができるようにすれば、Excel のオブジェクトを覚えなくて良いので、その点は楽かなと。

カテゴリー: 雑談, Excel VBA | 1件のコメント

Xcode 4.2 でUINavigationControllerを使う

UITableViewController と UINavigationController を使って画面を作ると、手軽に業務アプリ的な入力画面が作れるはずなのですが、この扱いが意外大変なのです…が、実は、Xcode 4.2 から導入された storyboard の機能を使うと「非常に簡単に」(と言っても以前に比較してというところでしょうが)、ページが扱えますという tips です。まぁ、実の処は、執筆中の本で使うサンプルなのですが。

imageimage

上記のようにテーブルの項目をタップすると、画面間を行き来できる、というツリー構造のアプリです。

■Xcode 4.2 で Master-Detail Application を選択

XCode で既にテンプレートが用意されているので、これを使います。「Master-Detail Application」を選択すると、上記のようなアプリのひな型が作成されます。

image

アプリケーション名を「SampleNavi」のように付けます。「Use Core Data」のところで、おそらくデータバインドができると思うのですが、テンプレートではチェックが外れています。このあたりは後日。

image

すると、下記のような3つの Controller が自動で作成されます。

image

  • Navigation Controller
  • Master View Controller ( TableViewController )
  • Detail View Controller ( ViewController )

Navigation Controller は、他の View のページ遷移を扱っているコントローラーです。TableViewController や ViewController の上についてナビゲーターのバーがこれにあたります。ページを戻るためのボタンが自動で出てきます。

■ファイルとの対応

image

実際のファイルとの対応は、

  • Master View Controller(UITableViewController) が、MasterViewContoller.h
  • Detail View Controller(UIViewController)が、DetailViewController.h

となっています。Master ページはひとつなので、基本は MasterViewController.h には手を入れません。また、DetailViewController は、遷移先の View に対してひとつ作るようにすると楽です。勿論、TableView の項目が同じ View を共有する場合は、DetailViewController でも構いません。

さて、storyboard の View とソースファイル(*.h, *.m)との対応をどのように取っているかというと、左側の画面で「Detail View Controller – Detail」を選択した後で、右側の Show the identity inspector のアイコンをクリックします。

image

すると、Class のところに、「DetailViewController」と表示されています。

image

これが、storyboard の View とコードファイルの対応になります(実際にはクラス名)。

■Detail 画面を増やす

さて、ここでもうひとつ Detail 画面を増やしてみましょう。

まず、Master View Controller の Table View Cell をクリックして、コピー&ペーストします。名前を「Other」に変えておきます。

image

追記 ~ Cell を2回クリックして attributes inspector で設定します。

20130508_01

同じように、Detail Controller View をコピーして、ペーストします。この時点では、ナビゲーターのバーはありません。

image

再び、Table View Cell の 「Other」を選択した状態で、右側の「Connection inspector」を開きます。

image

「push」の connection を、新しく作った ViewController に接続させます。

image

すると、自動的にナビゲーションバーが追加されます。名前が「Detail」のままなので、「Other」に変更しておきます。

image

■ソースコードを作成する。

DetailViewController クラスをひな形にして、OtherViewController クラスを作成します。Finder でファイルをコピーして、内部のクラス名を「DetailViewContoller」から「OtherViewController」に変更しておきます。

2つのファイルをプロジェクトに追加します。

image

■OtherViewContoller クラスを結びつける

新しく追加した Other View Controller を選択して、identity inspector を開いて、結び付けるクラスを「OtherViewController」に変更します。

image

これで、新しい View が、追加した OtherControllerView と結び付けられます。

■実行してみる

imageimage

実行してみると Master から Detail、Master から Other 画面への遷移ができているのが分かります。ここでは、Detail と Other とが同じ ラベルの表示になっているので、遷移のテストをするときに文字などを変えてみると分かり易でしょう。

あとは、View に対するクラスが異なるので、自由に画面を作っていけば ok です。サンプル画面を作るときに、View の遷移のコーディングが大変だったりするのですが、master-detail のテンプレートを使うと、非常に簡単です。詳細ページを増やす場合は、Other ページと同じ要領で ViewController を増やしていけばいいのです。

…というメモを残しておかないと、自分自身が忘れてしまうので、おすそ分けということで。

カテゴリー: Objective-C | Xcode 4.2 でUINavigationControllerを使う はコメントを受け付けていません

[VB] VB6.0風にVB.NETでデフォルトプロパティを作る

前回、[C#] VB6.0風にC#でデフォルトプロパティを作る | Moonmile Solutions Blog の続きです。と言うか、こっちを先に書かないと訳が分からないですよね。

Public Class Form1

	''' <summary>
	'''  インデックスを利用した例
	''' </summary>
	''' <param name="sender"></param>
	''' <param name="e"></param>
	''' <remarks></remarks>
	Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
		Dim obj As New DefaultClass
		' 配列も関数呼び出しも「()」なので、関数呼び出しに見えるのが難点か
		Debug.Print(obj(10))
		Debug.Print(obj("key"))

		Debug.Print(obj.Item(10))
		Debug.Print(obj.Item("key"))

	End Sub

	''' <summary>
	''' 暗黙の型変換を使う
	''' </summary>
	''' <param name="sender"></param>
	''' <param name="e"></param>
	''' <remarks></remarks>
	Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
		Dim obj As New DefaultClass

		Dim name As String = obj
		Debug.Print("name:{0}", name)
		Dim num As Integer = obj
		Debug.Print("num:{0}", num)

	End Sub
End Class

Public Class DefaultClass
	Public Sub New()
		Me.ItemName = "DefaultClass"
		Me.ItemNum = 10
	End Sub

	''' <summary>
	''' デフォルトプロパティを作る
	''' </summary>
	''' <param name="i"></param>
	''' <value></value>
	''' <returns></returns>
	''' <remarks></remarks>
	Default Public ReadOnly Property Item(i As Integer) As String
		Get
			Return String.Format("item-int {0}", i)
		End Get
	End Property
	Default Public ReadOnly Property Item(name As String) As String
		Get
			Return String.Format("item-name {0}", name)
		End Get
	End Property

	Public Property ItemName As String
	Public Property ItemNum As Integer
	''' <summary>
	''' 暗黙のキャスト
	''' </summary>
	''' <param name="obj"></param>
	''' <returns></returns>
	''' <remarks></remarks>
	Public Shared Narrowing Operator CType(obj As DefaultClass) As String
		Return obj.ItemName
	End Operator
	Public Shared Narrowing Operator CType(obj As DefaultClass) As Integer
		Return obj.ItemNum
	End Operator
End Class

もともと、既定のプロパティという考え方が、VB6.0から来ているので(正確にはVB3.0の頃ですかね?)VB.NET のほうが素直に書けます。
「obj(10)」のようにインデックスを使う場合には、「Default」というキーワードを使います。上記のソースの場合には、Item プロパティを多重定義しているので、Integer 型、String 型の両方の Item プロパティの定義に Default を設定します。

暗黙の変換のほうは「Narrowing」というキーワードですね。これが C# の implicit にあたります。逆に、明示的な変換のほうは「Widening」というキーワード。C# で云えば explicit です。

暗黙の変換を使うと、

Dim name As String = obj
Debug.Print("name:{0}", name)
Dim num As Integer = obj
Debug.Print("num:{0}", num)

という書き方ができて、対象のオブジェクトから値を取り出すときに便利です(つーかかえってややこしいかも)。取り出す利用者側として、「name」「num」の型はわかっているので「name = obj」、「num = obj」とやっても、それぞれの string 型、integer 型を類推させることが可能、ということです。普通は「name = obj.name」のように目的のプロパティを指定する訳ですが、取り出す string 型が一種類しかないのであれば「name = obj」としても良かろうという意味ですね。

本当は、「obj = name」のように逆向きも作りたいところなのですが、単純な代入演算子(=演算子)はオーバーライドできないので、無理なのです。仕方がないので二項演算子と組わせた「*=」とか「+=」とかならば可能なので、その話は後日。「+=」はデリゲート関係で使っていますね。

カテゴリー: VB | [VB] VB6.0風にVB.NETでデフォルトプロパティを作る はコメントを受け付けていません

[C#] VB6.0風にC#でデフォルトプロパティを作る

VB6.0の頃は、デフォルトプロパティというものがあって、
http://akihitoyamashiro.com/VBA/CreateDefaultProperty.htm

なところにあるように、「Attribute Value.VB_UserMemId = 0 」という属性(みたいなもの)を設定して、オブジェクトのプロパティを決めていました。まあ、大ざっぱに言えば、「obj.Item(10)」のように配列にアクセスするときに、「obj(10)」のように、Itemメソッドを省略できるという技です。普通は Item というメソッドが使われるのですが、このメソッド名は「Attribute Value.VB_UserMemId = 0 」を付けメソッド(プロパティ)の場合は、これが省略できるという仕組みです。

で、これを C#, VB ならばどうやるか、という話を少し。

private void button1_Click(object sender, EventArgs e)
{
	DefaultClass obj = new DefaultClass();
	Debug.Print(obj[10]);
	Debug.Print(obj.Item(10));
	Debug.Print(obj["key"]);
	Debug.Print(obj.Item("key"));
}

private void button2_Click(object sender, EventArgs e)
{
	DefaultClass obj = new DefaultClass();
	// string 型に暗黙の変換
	string name = obj;
	Debug.Print("name:{0}", name);
	// int 型に暗黙の変換
	int num = obj;
	Debug.Print("num:{0}", num);
}

「既定のプロパティ」という機能をちょっと拡大解釈して、添え字(あるいは添え文字列?)で扱う時のメソッドと、単純にオブジェクトから別の型に変換されるときのプロパティ、という風に分けてみました。

■添え字を使う場合

「obj.Item[10]」と「obj(10)」が同じような動作をするためには、次なように、this[…] のように書きます。[] 演算子は多重定義が効くので、int型とstring型の両方を一度に作れます。配列風なものと連想配列風なものですね。これは、string型だけじゃなくて、任意のobject型も使えるので結構不思議な使い方ができます。

public string Item(int i)
{
	return string.Format("item-int:{0}", i);
}
public string Item(string name)
{
	return string.Format("item-str:{0}", name);
}
// Default と同じ扱いが可能
public string this[int i]
{
	get { return this.Item(i); }
}
// 連想配列風に
public string this[string name]
{
	get { return this.Item(name); }
}

ちなみに、[] 演算子は、ふたつ以上の引数を持つことができるので、obj[x,y] のようなアクセスの仕方もできます。定義は↓のようですね。

// 引数が二つある場合
public string this[int x, int y]
{
	get { return string.Format("{0} {1}", x, y); }
}

■暗黙の変換を使う

もうひとつ、implicit を使って暗黙的に変換させることができます。普通は、自前で作成したクラスからstring型のプロパティを取り出すには、ToString メソッドをオーバーライドしたりしますが、もっと端的にキャストを使っても良いわけです。↓のように、DefaultClass 型から、string型やint型に自動で変換してくれます。

rivate void button2_Click(object sender, EventArgs e)
{
	DefaultClass obj = new DefaultClass();
	// string 型に暗黙の変換
	string name = obj;
	Debug.Print("name:{0}", name);
	// int 型に暗黙の変換
	int num = obj;
	Debug.Print("num:{0}", num);
}

これを実装するためには、implicit を使って、string型や int型に自動的に変換されるようにします。ちなみに、implicit は暗黙変換なので、明示的な変換(キャスト)を使いたい場合は、explicit を使えば ok です。

public string ItemName { get;  set; }
public int ItemNum { get;  set; }

/// <summary>
/// 暗黙変換(string型)
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static implicit operator string( DefaultClass obj ) 
{
	return obj.ItemName;
}
/// <summary>
/// 暗黙変換(int型)
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static implicit operator int(DefaultClass obj)
{
	return obj.ItemNum;
}

これが何に役に立つかというと…あまりにトリッキー過ぎて役に立たないというか、文法的に不思議な感じになってしまというか、妙な感じになるので、多用するのはちょっと、という気になります。

…が、いま作っている ExDoc という XML をパースするライブラリは、このあたりを使っていて配列をstring型に自動変換したり、コレクションから単一のオブジェクトに代入するときに暗黙にキャストをしていたりします、という詳細は別の機会に。ソースコードは git にあるので、moonmile/ExDoc – GitHub ご覧ください。ただ今、HTML のパースを準備中。

カテゴリー: C# | 1件のコメント