前回は Google ドキュメントのスプレッドシートに対して操作してみたので、次はカレンダーに予定を登録してみます。
DataGridView や DataRepeater にこだわりつつ
時代は Workflow Foundation などと言い続けていたら
これからは LogicFlow だろ! と思い始めてきた
色々浅く広くやっていく古い技術者の Blog
2011年12月29日木曜日
2011年12月26日月曜日
GData API を利用してスプレッドシートの値を取得する
Google Document では多くの API が提供されており、それを用いる事で Google が提供しているサービスへのアクセスを比較的簡易に行う事ができるようになっています。今回は色々理由があったのもあり、スプレッドシートに書かれている値を取得する、というのを行ってみました。
2011年12月23日金曜日
Powershell 3.0 と Workflow Foundation
※これは PowerShell Advent Calendar 2011 用の投稿です
PowerShell の最新版 3.0 では多くの機能強化が行われています。あまり深くチェックしていなかったのですが、@mutaguchi さんのツイートから興味を持って調べてみると、WF の機能を PowerShell から利用したり、逆に PowerShell の機能を WF で利用することができるようになっていました。 3.0 では多くのクラスが追加されており、半分ほどは WF で PowerShell を利用できるようにしたアクティビティクラスです。内部的に PowerShell のコマンドレットを Invoke で呼び出しているとの事で、これを利用することにより既存 PowerShell スクリプトのワークフロー化というのも可能になっています。
2011年12月21日水曜日
VB6 でもクラスは役に立つ
※これは VB Advent Calendat 2011 用の投稿です
元々私は VB2 からの VisualBasic プログラマだったりします。お仕事としても VB を利用していますが、まだまだ VB6 は廃れないなー、というのが率直なところです。
VB6 を利用されている場合、言語上の仕様もありあまりクラスを利用するメリットが見いだせないかと思われます。特定のケースに限り利用するだけで、結構使われていない。または使った事のない方も多いのではないでしょうか。ですが、VB6 でもクラスを利用する事で役立つことは多くあるのです。
CLR/H 第 65 回勉強会レポート
12/17 に行われた CLR/H 勉強会のレポートです。今回は昨年のカソウ化デイで好評?だったかもしれないことがなきにしもあらず、という事があり、ハイパーカソウ化デイとして「仮想化の話題を扱う」予定だったものが、フタをあけてみると仮想化の話ほとんどないよ!という楽しい勉強会になりました。
2011年12月19日月曜日
CLR/H 第 65 回勉強会で利用した LT スライド
今回の勉強会にて利用した LT のスライドをアップしておきます。
今回の内容は WMI + WF で運用管理作ろうよ、という内容でした。今後登場する PowerShell 3.0 によってその流れはますます加速すると思います。
2011年12月16日金曜日
文字列で指定した VB ソースを実行する
※これは VB Advent Calendat 2011 用の投稿です
Workflow Foundation では Assign アクティビティに代表されるように色々なアクティビティにて VisualBasic 構文を用いた記述が利用できます。この仕組みを利用すると、テキストファイル等に保存した VisualBasic ソースをそのまま解析し実行させることが可能です。
2011年12月9日金曜日
VB の xaml と C# の xaml
※これは VB Advent Calendat 2011 用の投稿です
ネット上で調べ物をしていると C# で書かれている記事に出会う事が多々あると思います。基本的なロジックは、コード変換を行っているサービスを利用するなど C# を知らない人でもどうにかする方法が用意されています。ですがコードだけではなくxaml 上でも C# と VB では違いがあります。
2011年12月5日月曜日
MethodInfo からのインテリセンス用ヒント文字列の生成
現在 α 版としてですが、インテリセンスにある程度対応した状態にて WF Designer Express をアップさせてもらっています。インテリセンス自体もまだまだ改良中ですが、その際に表示するツールチップヒントの文字列生成というのが、なかなかよく分かっていなかったのでまとめてみました。
2011年11月23日水曜日
2011年11月22日火曜日
IExpressionEditorService と IEXpressionEditorInstance でインテリセンスの導入
ある程度 WF の ExpressionTextBox で式や値の入力中にインテリセンスを利用するように実装できてきたので、その利用方法や注意点をまとめてみます。
まず WF での ExpressionTextBox におけるインテリセンスサポートですが、Visual Studio 上でワークフローを触られている場合は Visual Studio が提供するインテリセンスが自動で利用されています。しかし再ホストを行っているケースでは、自前でインテリセンス部分を用意しなくてはいけません。海外 MSDN だと VIsual Studio のアドイン Dll をそのまま利用してしまえという豪快な方法を目にすることがありますが、配布が出来ませんので自分一人の環境で利用する場合のみ許される方式です。
2011年11月19日土曜日
CLR/H 第 64 回勉強会での LT スライド
本日 11/19 に行われている CLR/H 第 64 回勉強会にて発表した LT スライドを公開します。今回は WF を利用して WPF アプリを作ってみよう、という題材です。もう少しあれこれできれば、ノベルゲーなら十分作れるんじゃないかな、と思いますw
2011年11月15日火曜日
ワークフロー上のアクティビティを非同期に複数動作させるには
原則として Workflow Foundation は非同期にて動作しますが、俗に言うマルチスレッドにタスクを分配して動作するような挙動は行いません。Parallel アクティビティというのもありますが、これも内部ではシングルスレッドで動作しており、待ち状態が発生した際に制御を切り替えるというものになっています。
このあたりで色々考える人は多いのですが、海外の Blog ですばらしいサンプルを見つけたので VB に移植してみました。
2011年11月9日水曜日
属性指定から IRegisterMetadata.Register へ
前回の LocBAML を利用した記事にあるように、現在拙作の WFDesignerExpress を多言語対応(といっても機械翻訳での対応ですが……)を行っています。その際に非常に感じたのは、クラスやプロパティに対して属性を設定するのではなく、IRegisterMetadata.Register メソッドにて属性の設定を行うようにするのが、WPF や WF でのプログラミングを行う際に適している、というところです。
2011年11月7日月曜日
.NET 4 における LocBAML を利用した多言語対応
アプリケーションの多言語化対応というのは、人によっては必要な作業だと思います。MSDN でもローカライズ関係の資料が色々と掲載されており、その中の一つの方法として LocBaml ツールを利用したローカライズがあります。
2011年11月6日日曜日
InArgument(T) から String への変換
アクティビティを色々作成している中で、次のようなケースがありました。
- デザイナ上で指定した画像のイメージをデザイナ上にプレビュー表示する
アクティビティのプロパティとしてファイル名を受け取るとして、そのファイル名で指定された画像をデザイナ上でプレビュー表示をする、というものです。その際にプロパティが String で指定されているのであればまだ簡単なのですが、アクティビティの場合ほとんどのプロパティは InArgument(T) を指定することもあり、値の変換には少し方法を変える必要があります。
2011年11月4日金曜日
Zip 圧縮を外部ライブラリ無しで行うアクティビティ
WF でファイルやフォルダ操作を行う上で必要性を非常に感じているのが Zip 圧縮。バッチスクリプト等での定型処理でも結構使われているのではないでしょうか。
これを実際に .NET で行おうとすると何種類かの選択肢から方式を選ぶことになると思います。
- J# ライブラリを利用する
- DotNetZip 等の外部ライブラリを利用する
- Windows 標準機能を利用する
自分が今まで利用していたのは(1)の方法で、これだと MS 純正コンポーネントのみで済み、かつ結構楽な手段でサンプルもごろごろ転がっていたと思います。ところが、.NET 4 から J# を利用するというのが結構面倒でそのままでは利用できないため WF から利用するのは躊躇していました。
そうなると(2)か(3)なのですが、(2)のように外部ライブラリを利用するのは最も楽で安定するのですが、気持ちとして参照 Dll がどんどん増えていく事が嫌いというのもあり却下。必然的に(3)の方法となってしまいます。
2011年11月2日水曜日
MessageBoxIcon の値を IValueConverter で変換
メッセージボックスを表示するアクティビティを作っていて、デザイナ上でアイコンやボタンの設定をラジオボタンにて選択させようとした時、MessageBoxIcon 列挙値を変換するような IValueConverter を用意してあげれば、ラジオボタンにバインドができて非常に楽になります。ただし、その際に少しだけ注意する点がありました。
2011年11月1日火曜日
アクティビティの検証(2)
前回は属性による指定と CacheMetadata メソッド内部での検証ロジック実行という方法を利用しましたが、今回は制約(Constraint)による検証を行ってみます。制約とは MSDN にも記載されている通り「検証ロジックを含むアクティビティ」となっています。そのためコードだけでなく XAML によっての作成も可能です。
2011年10月31日月曜日
アクティビティの検証(1)
2011年10月27日木曜日
WF4 と WF4.5 における XAML 出力の違い
WF4 と WF4.5 では出力される xaml ファイルの中身がかなり異なっています。それに伴い、WF4 での一部問題も解決されています。
例えば Sequence アクティビティの中に WriteLine アクティビティを置いただけのワークフローにインポートの設定を行ったものを xaml に出力した場合、WF4 と WF4.5 ではこのように出力の違いがあります。まずは WF4 の場合です。
2011年10月25日火曜日
SourceLocationProvider.CollectMapping メソッドは WorkflowDesigner.Load(ファイル名) が必要
最近自作ツールのデザイナーをちまちまやっているのですが、その中で微妙な気持ちながらも未だに対応策が見えていない点が一つ。
ビジュアルデバッグトレースという感じに、ワークフローの実行状況をデザイナ上で表示するために色々やる必要があるのですが、その中に SourceLocationProvider.CollectMapping メソッドを用いてワークフローファイルの内容と実際のアクティビティの内容とをマッピングする必要があります。
2011年10月24日月曜日
VB6 でコンソールアプリを作る
今までずっとできないできないと思っていたところ、@rinta100 さんに教えてもらいました。まずはリンクを。
How to create a VB6 console program
詳しいことはリンク先を見てもらうとわかると思いますが、コンパイル時に明示的にライブラリのリンクを行う( LINK.exe /EDIT /SUBSYSTEM:CONSOLE ~)ことで、コンソールアプリを作成できるようです。
これは正直驚きました・・・!
2011年10月21日金曜日
アイコン等のリソースと IRegisterMetadata
前回の記事で、外部ライブラリを動的に読み込みそのリソースを登録する際に、IRegisterMetadata.Register メソッドを呼ぶ、というものを書きました。この方法は現時点で Microsoft としても推奨している方法です。アイコンやアクティビティデザイナ等、今までは属性を利用して設定していたのですが、この方法であれば別 Dll に分離することができるようになります。WPF ではよく見かける形ですが、WF においても同様の方法を用います。
なお、ここで言う IRegisterMetadata インターフェースは System.Activities.Presentation.Metadata 名前空間に属するもので、WPF で利用する Microsoft.Windows.Design.Metadata 名前空間に属する同一名称のインターフェースとは別になります。
2011年10月19日水曜日
外部ライブラリの動的読み込み(仮)
Visual Studio 上で行っている分には自動で参照設定を行った Dll からアクティビティをツールボックスに追加、リソースの読み込み等を行ってくれているので、特に心配する事はないのですが、リホスティングデザイナにてこれを行う場合、少し気を付ける必要があります。
2011年10月16日日曜日
2011年10月13日木曜日
10/15 第 63 回 CLR/H 勉強会で利用するスライド
第 63 回勉強会で利用するスライドをアップしておきます。当日までにもう少し追加・調整するかもしれませんが、とりあえずという事で。
今回は WF4.5 の新機能についてさらっと説明するショートセッションです。
時間の都合によっては懇親会中、アイスブレーク的にやるかもしれませんw
2011年9月30日金曜日
WF 4.5 用の SQL Server (Azure) 永続化構成
WF では SQL Server で永続化するための設定用スクリプトがあらかじめ用意されています。今回 WF 4.5 となるにあたり、ワークフローインスタンスのバージョン管理機能が追加されたこともあり、その構成に追加が行われていました。
2011年9月29日木曜日
起動時にワークフローの引数を設定する
今回はコンソール実行用モジュールにて引数をコマンドラインオプションで渡せるようにしてみまして、このあたりをやってみて気付いた点があったので記載しておきます。
2011年9月27日火曜日
WF4.5 でリホスティングデザイナの Load ができない
Windows 8 とともに .NET Framework 4.5 も開発者向けプレビュー版が用意されているので、これも暇をみて触っている最近ですが、リホスティングデザイナが全くどうして動いてくれません。
よく分からないのは、TargetPlatform を .NET 4.5 にしたから発生しているのではなく、.NET Framework 4.5 DP をインストールしている環境であれば、TargetPlatform は 4 でも 4.5 でも発生してしまうという点です。
2011年9月22日木曜日
Codeplex にアップしました
今まで CLR/H にてオープンにしていた自作の WF4 用のリホスティングデザイナー。色々思うところがあって、Codeplex 上にアップ、開発していく事に決めました。
ちなみに以前に見せた際にあった、クラウディアさん関係機能は OFF というかコメントアウトしてありますw
それと再配布回りを調べきっていない状態でのアップですので、近日中に v0.2 とする予定です。リボン周りとか確かダメだったよなぁ・・・。
2011年9月21日水曜日
Annotations によるワークフロー上のコメント
2011年9月19日月曜日
2011年9月16日金曜日
XBAP で WF デザイナー
以前、CLR/H 61 回勉強会の際に @jsakamoto さんに言われて気になっていたのを実際に試してみました。それは WF リホスティングデザイナは XBAP だと簡単にブラウザ上で利用できるんじゃないのか、というもので、聞いていて
「そういえば XBAP なんてあったなぁ、でも使ったことないから、WPF アプリとの差がわからんなー」
なんて思っていたので実際に試してみました。
2011年9月15日木曜日
WF 4.5 における新機能のオンオフ
MSDN にて WF 4.5 の新機能関係を調べていてこのような記述があるのがわかりました。
今回の WF 4.5 にて追加される機能については、自由に On / Off が行える感じです。
DesignerConfigurationService として提供されるこのクラスを通して、新機能(アノテーション、自動接続、パンモード・・・)の On / Off を制御するプロパティが提供されるとのことです。このあたりが、リホスティングしている場合に設定を行う箇所と思われます。
興味をひくのは、LoadingFromUntrustedSourceEnabled や NamespaceConversionEnabled プロパティあたりですね。まだ開発者向けプレビューなので、今後変更されることも予想されますが、このような形での提供はありがたいですね。
Workflow Foundation 4.5 の新機能など
Windows 8 の開発者向けプレビューが登場したことに合わせて、.NET Framework 4.5 の情報も出始めてきました。MSDN にて色々書かれていますが、その中に Workflow Foundation の 4.5 における追加機能について記載があったので、意訳&勝手に解釈 してみます。
2011年9月14日水曜日
Windows 8 Developers Preview での VB6 アプリ
早速ダウンロード開始されていたので、Hyper-V上に環境を構築、VB6アプリの挙動を検証してみました。まだ本格的な検証は行っていませんが、軽く触った感じではかなり良好です。
2011年8月28日日曜日
2011年8月22日月曜日
WF 標準アクティビティのアイコン
2011年8月19日金曜日
8/27 CLR/H 第61回勉強会 WF ハンズオン用の資料
8/27 に行われる CLR/H 第 61 回勉強会のハンズオンとして、Workflow Foundation のセッションを行います。前回はスライドを用いた通常形式のセッションでしたが、今回は参加者が各自 PC を用意した上で実際に実装していただくハンズオン形式となります。
その際に参照していただく資料を用意しました。
当日はこの資料を元に、スライドも交えた形で行う予定です。 Ustream での中継も行いますので、遠隔地の方も是非参加してみてください。
2011年8月9日火曜日
WF をコードのみで利用する場合の注意
2011年8月5日金曜日
標準アクティビティ+α でメール送信
Workflow Foundation を勉強するに当たり Microsoft からコードサンプルが提供されています。残念ながら英語のみで、サンプルの殆どは C# のみという VB 使いには厳しい現実ですが、その中で提供されている SendMail アクティビティのように、そのままでも結構使い出のあるアクティビティが存在しています。
2011年8月4日木曜日
標準アクティビティだけでファイル監視
あまりにも代わり映えのないタイトルが続いたので、今回からは Workflow で実行する内容をちゃんとタイトルに含ませるようにしますw
タイトルにもあるように今回実行するのは「特定のフォルダを監視してファイルが発生したら何かしらの処理を行う」という、フォルダ監視的なものです。
2011年8月3日水曜日
標準アクティビティだけで BAT ファイルを置換 (6)
今回は「フォルダ内にある、3 日前以前に作成されたファイルを削除」という処理を行ってみます。この処理を BAT ファイルで行うのは大変なのですが、需要はかなりあるのではないでしょうか。BAT ファイルのみで日付演算を行う事は、不可能ではないのですが非常に面倒です。その中でも楽に済ませたい場合は VBS を利用する事が多いと思います。
2011年8月2日火曜日
InvokeMethod アクティビティで利用できないメソッド
2011年8月1日月曜日
標準アクティビティだけで BAT ファイルを置換(5)
2011年7月29日金曜日
標準アクティビティだけで BAT ファイルを置換(4)
BAT ファイル上でシステム日付を利用する場合は、一手間というか色々と小難しい書き方を利用します。
2011年7月28日木曜日
標準アクティビティだけで BAT ファイルを置換(3)
2011年7月27日水曜日
標準アクティビティだけで BAT ファイルを置換(2)
BATファイル等で外部プロセスを起動する場合、かなりの割合で同期制御(終了するまで待機 = Start /w 等で実行)を行うのではないかと思います。これを普通にコーディングで実行するのであれば、次のようになります。
2011年7月26日火曜日
標準アクティビティだけで BAT ファイルを置換(1)
BAT ファイル等で行われている処理内容は多岐にわたると思いますが、その中の一つ「別アプリケーションの実行」を標準アクティビティだけで置き換えてみようと思います。かなり力技です。
2011年7月24日日曜日
ファイル・フォルダ操作関係のアクティビティ
WF にてファイルやフォルダの操作をするアクティビティをある程度まとめて作ってみたので公開しておきます。各アクティビティにてやっている内容は非常に簡単なものなので、特に説明はいらないかと思います。なお、デザイナー上での直接入力にはまだ対応できていないので、次のアップデートなどで行う予定です。
ダウンロードはこちらから。
ジャンル | 機能 |
ファイル | ファイルのコピー |
ファイルの削除 | |
ファイルの存在チェック | |
ファイルのリネーム | |
フォルダ | フォルダの作成 |
フォルダの削除 | |
フォルダのリネーム | |
一覧 | ファイル一覧取得 |
フォルダ一覧取得 | |
その他 | 外部プロセス実行 |
ファイルに文字列を出力 |
2011年7月21日木曜日
2011年7月20日水曜日
WF セッションのフォローアップ(2)
もう一つセッションで話せなかった話題について。
バッチスクリプトの置き換えは、WF を利用してみるのに適しているケース、とあの場で言いましたが、それを行うに当たり少し注意する点があります。
WF アプリケーション的なスタイルで行うには外部 AP 起動は問題ありませんが、WF サービスでこれを行おうとした場合に権限の問題が発生します。IIS を利用してサーバー上でプロセス起動、と同様の問題で IIS 等でホスティングしている場合、IIS の実行アカウントに権限を設定する必要が発生します。セルフホストを行う場合では、ホストするプロセスがサービスの場合は同様に、サービス実行アカウントに対して権限の設定が必要です。
2011年7月19日火曜日
WF セッションのフォローアップ
1:コンポーネント指向とは
言葉の定義としては、「ソフトウェアを機能ごとに部品として分割、必要に応じて組み合わせて利用する」、というような考え方になります。WF はこの考え方を実現する事に非常に適しています。それは「アクティビティ=コンポーネント」となり、「必要に応じて組み合わせる」事がデザイナの提供により非常に容易になっている事が大きな理由です。
通常の開発においても、適宜機能の分割を行いライブラリ化することはよくある事と思います。ですが、このライブラリを「必要に応じて組み合わせる」ことは、開発者でなければ難しいと思います。ですが、WF であればドラッグ&ドロップにてアクティビティを配置し、必要であればプロパティを設定する程度ですので、開発者でなくとも「必要に応じて組み合わせる」事が可能となります。
ポイントは「開発者でなくとも」です。この部分が WF の大きなメリットとなります。
2011年7月17日日曜日
2011年7月16日土曜日
2011年6月15日水曜日
WCF の拡張機能
現時点で WCF 用の拡張機能が何個か用意されています。
WCF Web API はよくある Web サービスを構築するための追加機能で現在 Preview 4 となっています。今まででも REST 形式の Web サービスであれば対応できているのですが、Web API の利用により、より最近らしい Web サービスの構築ができるようになるとのこと。話自体は去年とかからみかけていたのですが全く試していません。
どうやら今までの WCF Web サービスよりも HTTP に関係した部分で、より細かい制御を行えるようになる、とのことですが・・・。
jQuery Support はその名前の通り、WCF Web サービスを jQuery から利用しやすい形で構築できるようにするものです。元々 WCF Web サービス自体、.Net なアプリからのアクセスを主軸に置いていた点が大きく、それ以外のアプリからアクセスできるようにするには、基本 REST 形式の対応が必要でした。jQuery は非常に著名で多くの場面で利用されているので、この対応はかなり嬉しい人も多いんじゃないかと思います。
Express Interop Bindings は上二つとちょっと毛色が異なり、特定のアプリと接続するための設定や実装をより容易にするためのものです。そしてこれは VisualStudio のアドインという形での提供ですので開発者向けとなっています。現時点で対応を示しているのは次のものとなっています。
- Oracle WebLogic
- Oracle Metro
- IBM WebSphere
- Apache Axis2
Wizard 形式で設定できるらしい記述がされています。試そうにも残念ながらここで対象となるシステムが手元にないので、こればかりはどうしようかなぁ。
なお、試してみるのあたり一つ注意点が。
jQuery Support を利用するには WCF RIA Services の新バージョンが必要となります。恐らくほとんどの人は WCF RIA Servies V1 (SP1) がインストールされているかと思いますが、必要となるのは WCF RIA Services V1 SP2 となっています。そしてこれは Preview(April 2011) 版でのみ提供されていますので、この点だけ注意してください。
2011年6月2日木曜日
デザイナ上で複数行コメントを入力可能なアクティビティ
2011年5月31日火曜日
Azure Blob ストレージへ REST API にてアップロードするアクティビティ(仮)
ストレージ関係の REST API を暇を見つけながらちろちろやっている最中ですが、とりあえずアップロード(ただし条件付き)ができるところまではできましたので、恒例のアクティビティ化をしてみました。
条件付き、というのは本来ストレージへアップロードを行う場合には何点か考慮しなくてはいけないポイントがあり、現時点ではその考慮点の一部にしか対応できていないためです。何を考える必要があるかと言うと、次の点になります。
- アップロードするファイルの容量
Windows Azure のストレージには大きくわけて 2 つの方式が提供されています。一つは BlockBlob と呼ばれる種類で、これは 64MB までの一つのファイル、または 4MB 単位に分割したファイル群という形でアップロードが可能です。分割するメリットは同時に複数セッションを利用してアップロード速度を向上させたり、エラー発生時のリトライ処理量を減らすなどがあたります。もう一つは PageBlob と呼ばれる種類でこちらは 1TB までのファイルを扱う事が可能な点と、バイト単位(イメージとしてはHDD等のセクタ)にて読み書きの処理が行える点がポイントとなります。現在ベータ版として提供されている Azure Drive (ストレージを通常の NTFS ドライブに見せかけて利用できる)は PageBlob をベースに作成されていると思われます。
2011年5月26日木曜日
Azure Storage REST API サンプル ~コンテナ関係~
Windows Azure Storage Services REST API という形で提供されている、REST 形式にて利用するストレージ関係のAPIの中で、コンテナ周りの API をアクティビティ化してみました。その際に色々分かったところもあるので、メモとして残しておきます。
コンテナ関係のAPI
List Containers | 現在のコンテナ一覧を取得する |
Create Container | コンテナを新規に作成する |
Delete Container | コンテナを削除する |
Get Container Properties | コンテナの情報を取得する |
Get Container ACL | コンテナのアクセス制限を設定する |
Set Container ACL | コンテナのアクセス制限を取得する |
Get Container Metadata | コンテナにメタデータを取得する |
Set Container Metadata | コンテナにメタデータを設定する |
カテゴライズした場合、もう一つ List Blobs という API もあるのですが、個人的にこれはBlob操作系と思っているので別の機会にします。
2011年5月25日水曜日
Azure Storage REST API の Authorization ヘッダ・改訂版
変更点は今のところ1か所のみです。
2011年5月20日金曜日
Azure Storage 関係の REST API で利用する Authorization ヘッダ
2011年5月19日木曜日
SQL Azure ファイアウォール管理 REST API のアクティビティ化
基本的に前回とほぼ同一ですが、SQL Azure のファイアウォール制御(作成・列挙・削除)もアクティビティ化してみました。ファイアウォール制御 API 自体は特に難しいものでもなく、非常に簡単な形式となっています。メッセージ生成が必要なのも新規作成の際のみです。
前回同様ベースとなるクラスから。
2011年5月18日水曜日
SQL Azure Management REST API をアクティビティ化
今回はサーバー管理用の REST API をアクティビティ化してみました。REST API 利用ですので、SDK 等の導入は一切必要ありません。
殆ど似た形になるので今回はベースクラスを作成し、各アクティビティはそれを継承する形にしています。まずはベースとなるアクティビティクラスから。
2011年5月17日火曜日
Windows Azure のサブスクリプション操作履歴を取得するアクティビティ
今回もいきなりソースを。
2011年5月16日月曜日
Windows Azure Management REST API でホスティング一覧を取得するアクティビティ
Windows Azure 管理ポータルで目視できる内容ですが、定期的に監視などする事を考えるとスクリプトまたはプログラム化する必要が高くなります。また SDK でマネージド DLL 等も配布されていますが、端末にそれを入れるのも億劫ですw
そのような場合は、REST API が提供されているのでこれを利用した監視等々を行う事になるかと思います。実際に REST API を利用するには一つだけ事前準備が必要です。
-
管理用証明書を作成、設定する
できあがった証明書は自分の環境にインストール(作成した cer ファイルをダブルクリック等で実行するとインポートができます)、Windows Azure 管理ポータルからもインポートします。
インポートすると管理ポータルでこのように確認ができます。ここで表示されている値で、ThumbPrint と書かれている値が後々必要になりますのでメモしておきます。
これでアクティビティの実装を行います。
Workflow に引数を設定して実行
引数を渡す場合は、このような形で Dictionary を作成し WorkflowApplication や WorkflowInvoker に引き渡します。詳しく調査していないのですが、恐らく WorkflowApplication.HostEnvironment を通しても同様にアクセスできるのではないかな、と思っていますが試していませんw1: '入力引数の設定
2: Dim inArgs As New Dictionary(Of String, Object)3: inArgs.Add([引数名], Value)4:5: Dim wfApps As New WorkflowApplication(wfFile, inArgs)
反対に結果を受け取る場合のロジックは次のようになります。
2011年5月13日金曜日
REST っぽい Workflow サービスの公開
ですが WCF の機能を利用する事により「それっぽい」形に仕上げる事はできます。
2011年5月11日水曜日
IActivityTemplateFactory による カスタムアクティビティの統合
そのような場面では IActivityTemplateFactory インターフェースを継承したクラスを用意し、デザイナにドロップした際に複数アクティビティを自動で展開させる事が可能です。
2011年5月10日火曜日
Workflow サービスを Windows Azure 上で公開する
2011年5月9日月曜日
Workflow 上の Receive アクティビティと WCF での実装
Workflow 上で Receive アクティビティ等を利用し送受信を行うサービスを構築できるのは以前の記事などで書いた通りです。それをWCFでロジックを組んだ場合にどうなるか、というのを比較してみると各プロパティでの設定がなんとなくでも見えてくるかと思います。
1: <ServiceContract()>2: Public Interface IService13:4: <OperationContract()>5: Function GetData(ByVal value As Integer) As String6:7: End Interface
このソースが Receive アクティビティを利用した場合をWCFにて表したソースとなります。アクティビティ上で OperationName プロパティで指定した名称はそのまま Function 名となり、WorkflowService の Name プロパティで指定したものがインターフェース名(≒クラス名)となります。Receive アクティビティの Content で指定したものは、Function の引数として定義、または DataContract 属性を付与したクラスとなります。
このような事を自動で行っているために、WCF ではできている事が Workflow 上ではできていない点もあります。一つが Function に対しての属性付加 ( WebGet とか ) で、これができないので REST サービスとしての Workflow が行えていません。
ただ上記のようなロジックを組み、コード上で Workflow を利用する形式であればRESTであろうと行えるので、やりようはあるのですが Workflow 単体では残念ながらまだ手段がわかっていません。
2011年5月6日金曜日
IIS Express での Workflow サービスホスティング
IIS で Workflow サービスのホスティングを行う場合の操作について以前の記事で書きました。この方法は IIS Express でも当然有効ですが、一点だけハマった部分があるので書き残しておきます。
- Windows Server AppFabric をインストールしている
- AppFabric ランタイム機能のホスティングサービスを有効にしている
- AppFabric ホスティングサービスにて永続化構成を設定していない
ネックとなったのは Windows Server AppFabric です。これは Windows Vista 以降の IIS で利用できるものなので、自分の Windows7 クライアントにもインストールはしていたのですが、何も設定を行っていなかったため、今回の現象に遭遇しました。厄介なのは、これが IIS 利用時には発生せずに IIS Express 利用時のみに発生する現象だった、という点です。
これが Windows Server AppFabric の「機能の追加/削除」の GUI です。添付したイメージではホスティングサービスの機能が無効になっています。この状態であれば今回の現象は発生しません。
こちらが「Configure AppFabric」のGUIです。このように「未設定」の場合に問題が発生します。
この状態で、IIS Express にて Workflow サービスをホスティングし呼び出してみると永続化のエラーが発生します。AppFabricPersistenceDB にログインできません、というエラーです。永続化の設定など、全く行っていなかったので最初は分かりませんでした。例外の情報からAppFabric関連というのは分かるのですが、設定を何も行っていなかったのもあり最初はお手上げでした。色々と試行錯誤の末、AppFabric のホスティングサービス自体を無効にしておけば回避できました。
ここさえ回避してあれば、IIS Express でも簡単に Workflow サービスが利用できます。必要なのは xamlx と web.config の 2 ファイルだけです。IIS Express は XP 環境でも動作しますので、XP 上で Workflow サービスを構成することもできます。
TrackingRecord によるトラッキング
WF の仕組みとして TrackingRecord によるトラッキングの仕組みが用意されています。これはワークフローが、またはアクティビティが何か動作をするたびに通知されるレコードで、全部で 13 種類の状態が通知されます。各トラッキングレコードが何を伝えてくれるかは MSDN を参照してください。
TrackingRecord : WorkflowInstanceRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 0, EventTime = 2011/05/02 9:59:55, ActivityDefinitionId = Sequence, State = Started }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 1, EventTime = 2011/05/02 9:59:55, Activity { Name=Sequence, ActivityId = 1, ActivityInstanceId = 1, TypeName=System.Activities.Statements.Sequence }, State = Executing }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 2, EventTime = 2011/05/02 9:59:56, Activity { Name=Assign, ActivityId = 7, ActivityInstanceId = 2, TypeName=System.Activities.Statements.Assign }, State = Executing }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 3, EventTime = 2011/05/02 9:59:56, Activity { Name=Assign, ActivityId = 7, ActivityInstanceId = 2, TypeName=System.Activities.Statements.Assign }, State = Closed }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 4, EventTime = 2011/05/02 9:59:56, Activity { Name=Delay, ActivityId = 5, ActivityInstanceId = 3, TypeName=System.Activities.Statements.Delay }, State = Executing }
TrackingRecord : WorkflowInstanceRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 5, EventTime = 2011/05/02 9:59:56, ActivityDefinitionId = Sequence, State = Idle }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 6, EventTime = 2011/05/02 9:59:57, Activity { Name=Delay, ActivityId = 5, ActivityInstanceId = 3, TypeName=System.Activities.Statements.Delay }, State = Closed }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 7, EventTime = 2011/05/02 9:59:57, Activity { Name=メッセージを表示, ActivityId = 2, ActivityInstanceId = 4, TypeName=Workflow4.Command.DisplayActivity }, State = Executing }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 8, EventTime = 2011/05/02 9:59:58, Activity { Name=メッセージを表示, ActivityId = 2, ActivityInstanceId = 4, TypeName=Workflow4.Command.DisplayActivity }, State = Closed }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 9, EventTime = 2011/05/02 9:59:58, Activity { Name=Sequence, ActivityId = 1, ActivityInstanceId = 1, TypeName=System.Activities.Statements.Sequence }, State = Closed }
TrackingRecord : WorkflowInstanceRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 10, EventTime = 2011/05/02 9:59:58, ActivityDefinitionId = Sequence, State = Completed }
実際にトラッキングを行った際には、上記のようなレコードが通知されます。この内容は前回の記事で実際に実行した際の内容です。デザイナ上でトラッキング内容に基づいて表示を行うのですが、その前に追跡用のプロファイルを作成する必要があります。これは「何をトラッキングし通知するか」を設定するものです。
1: 'トラッキングプロファイルの生成
2: customTracker = New VisualTrackingParticipant '独自に用意したトラッキング用クラス3: Dim trcProfile As New TrackingProfile With {.Name = "CustomTrackingProfile"}4: 'トラッキングが必要なアクティビティの名前を設定
5: Dim ctQuery As New CustomTrackingQuery With {.Name = "*", .ActivityName = "*"}6: trcProfile.Queries.Add(ctQuery)7: 'トラッキングが必要なステータスを設定
8: Dim wfiQuery As New WorkflowInstanceQuery9: wfiQuery.States.Add(WorkflowInstanceStates.Started)10: wfiQuery.States.Add(WorkflowInstanceStates.Aborted)11: wfiQuery.States.Add(WorkflowInstanceStates.Canceled)12: wfiQuery.States.Add(WorkflowInstanceStates.Completed)13: wfiQuery.States.Add(WorkflowInstanceStates.Idle)14: wfiQuery.States.Add(WorkflowInstanceStates.Persisted)15: wfiQuery.States.Add(WorkflowInstanceStates.Resumed)16: wfiQuery.States.Add(WorkflowInstanceStates.Suspended)17: wfiQuery.States.Add(WorkflowInstanceStates.Terminated)18: wfiQuery.States.Add(WorkflowInstanceStates.UnhandledException)19: wfiQuery.States.Add(WorkflowInstanceStates.Unloaded)20: wfiQuery.States.Add(WorkflowInstanceStates.Unsuspended)21: trcProfile.Queries.Add(wfiQuery)22: 'ステータスのトラッキングが必要なアクティビティの名前を設定
23: Dim asQuery As New ActivityStateQuery With {.ActivityName = "*"}24: asQuery.States.Add("*")
25: asQuery.Variables.Add("*")
26: trcProfile.Queries.Add(asQuery)27:28: customTracker.TrackingProfile = trcProfile29: _wfApps.Extensions.Add(customTracker)
トラッキングプロファイルを設定するのはこのようなロジックとなります。作成したプロファイルを、WorkflowApplication の Extensions として追加していますが、これは WorkflowInvoker も同様です。
1: Imports System.Activities
2: Imports System.Activities.Tracking
3: Imports System.Collections.Generic
4:5: Public Class VisualTrackingParticipant6: Inherits Tracking.TrackingParticipant
7:8: Public Event TrackingRecordReceived As EventHandler(Of TrackingEventArgs)9:10: Public Property ActivityIdToWorkflowElementMap As Dictionary(Of Integer, activity)11: Public Property ActivityElementMap As Dictionary(Of Object, Debugger.SourceLocation)12:13: Protected Overrides Sub Track(ByVal record As System.Activities.Tracking.TrackingRecord, ByVal timeout As System.TimeSpan)14: OnTrackingRecordReceived(record, timeout)15: End Sub16:17: Protected Sub OnTrackingRecordReceived(ByVal record As TrackingRecord, ByVal timeout As TimeSpan)18:19: Dim resultArgs As New TrackingEventArgs With {.Record = record, .Timeout = timeout}20: Select Case True21: Case TypeOf record Is WorkflowInstanceRecord '10022: Case TypeOf record Is WorkflowInstanceUnhandledExceptionRecord '10123: Case TypeOf record Is WorkflowInstanceAbortedRecord '10224:25: Case TypeOf record Is ActivityStateRecord '10326: If ActivityIdToWorkflowElementMap.ContainsKey(DirectCast(record, ActivityStateRecord).Activity.Id) Then27: resultArgs.Activity = ActivityIdToWorkflowElementMap.Item(DirectCast(record, ActivityStateRecord).Activity.Id)
28: End If29: Case TypeOf record Is ActivityScheduledRecord '10430: If ActivityIdToWorkflowElementMap.ContainsKey(DirectCast(record, ActivityScheduledRecord).Activity.Id) Then31: resultArgs.Activity = ActivityIdToWorkflowElementMap.Item(DirectCast(record, ActivityScheduledRecord).Activity.Id)
32: End If33: Case TypeOf record Is FaultPropagationRecord '10534: Case TypeOf record Is CancelRequestedRecord '10635: Case TypeOf record Is BookmarkResumptionRecord '10736: Case TypeOf record Is CustomTrackingRecord '108,110,11137:38: Case TypeOf record Is WorkflowInstanceSuspendedRecord '11239: Case TypeOf record Is WorkflowInstanceTerminatedRecord '11340:41: End Select42: RaiseEvent TrackingRecordReceived(Me, resultArgs)43:44: End Sub45: End Class46:
独自に用意したトラッキング用クラスはこのようなロジックで行っています。内容としては対象アクティビティが関連する ActivityStateRecord や ActivityScheduledRecord が通知された際に、TrackingRecord の内容から対象アクティビティを確定させてイベントに通知させることを行っています。イベント受け取り側ではこの内容を元に、WorkflowDesigner.DevugManagerView.CurrentLocation にその時点でのアクティビティを設定する事で、デザイナ上に黄色い枠線で囲まれて表示が行われるようになります。
2011年5月3日火曜日
リホスティングデザイナにて引数を設定
今までのリホスティングしたデザイナのスクリーンショットでは引数の設定ができていませんでした。調べてみるとちょっと一手間加えてあげる必要がある、と海外 MSDN フォーラムにて問い合わせされていたのでそれを試してみました。
1: Dim wfFile As Object = New Sequence
2:
3: Dim activityBuilderType As New ActivityBuilder
4: activityBuilderType.Name = "ActivityBuilder"
5: activityBuilderType.Implementation = wfFile
6: designer.Load(activityBuilderType)
このような形で ActivityBuilder にてアクティビティをラップするようにし、それをデザイナ上でロードすることで引数の設定ができるようになります。
ただし今の時点で自分が調べ切れていないのですが、以前に書いた WorkflowService の場合はこの方法が利用できない様子です。まぁサービスで引数はない(パラメータなどを利用するため)ので影響はないですが。
2011年5月2日月曜日
ワークフローのトラッキング
デザイナをリホスティングしている環境でも、ワークフローの実行トラッキングを行う事ができます。やること自体は非常に簡単で、
- 実行情報の出力
- 出力されたトラッキング情報を元にデバッガの位置を設定
この二つを行えばデザイナ上でのトラッキングが可能です。実際のロジックは次回以降にて掲載する予定ですので、今回はトラッキングを行った際の挙動を貼り付けておきます。
このような感じでトラッキングを行う事ができます。
2011年4月28日木曜日
Workflow サービスを Workflow 上で利用する
前回のように作成したワークフローサービスを、別のワークフロー上で利用する事も当然できます。動作原理は WCF によるサービスですので、当然コードのみでも利用できますし、VS 上で Web 参照を追加して利用する事もできます。ワークフロー上で利用する場合は、前回のサービス作成と逆のアクティビティを利用します。
これが全体図です。前回は 受信→返却送信、という流れで作成しましたが、サービスを利用する側となると 送信→返却受信という流れになります。やはり 1 セットで設置できるアクティビティが用意されており、それが SendAndReceiveReply アクティビティとなります。デザイナ上にドロップすると、Send アクティビティと ReceiveReply アクティビティが設置されます。リクエストを送信するための Send アクティビティではサービスを呼び出すための設定が必要です。
- EndpointAddress:サービスのアドレスをUriクラスのインスタンスとして設定
- Content:サービスへ送信する値やパラメータを設定
- ServiceContractName:サービス側で設定されている同名のプロパティと設定を合わせる
サービスからの結果を受信する ReceiveReply アクティビティでは Content プロパティに対して受け取る値やパラメータの設定だけが必要です。
このようにワークフローを設定し実行すると、前回作成した適当な値を返すワークフローサービスが動作し結果を返却してくれます。
WCF で提供されるサービスを利用する事自体かなり簡略化されていますが、ワークフローから利用する場合はさらに簡単で、一切のコーディング作業が必要ないことがわかると思います。またサービス自体もコーディング全く無しで準備可能ですので、開発者でなくともサービスを作成・提供することが可能です。
特に現在は Windows Azure にて IIS を利用する事が可能となっています。Azure Platform を利用する事で更に WF を有効に活用できるのではないでしょうか。
IIS による Workflow サービス公開
WF4 を利用して外部にサービスとして公開する方法としては何通りかありますが、その中でも比較的簡単にサービス公開する方法である、IIS を利用した方法です。IIS を利用してワークフローをサービス公開するには大きく分けて二つの作業が必要になります。
- ワークフローサービスとして公開するワークフローの作成
- IIS の設定
ワークフローサービスとしてのワークフローですが、実際には今まで利用しているワークフローと殆ど違いがありません。IIS でホスティングを行う場合があるので、拡張子が xaml ではなく xamlx を利用しているだけで、内部に記述されている内容には殆ど違いがありません。唯一の違いはルートレベルに利用するアクティビティを WorkflowService アクティビティにするだけです。
WorkflowService アクティビティにはプロパティが 3 つ公開されています。この部分でサービス名や config ファイル上の設定などを指定します。今回はサンプルという事で CodeRecipe で公開されているサンプルに近いものを作成します。サービスの処理内容としては、「適当な文字列を受け取って、適当に編集して、適当に返却する」というサンプルでしかありえない簡易な物とします。
サービスとして公開している場合、リクエストを受けるクチと返事を返すクチが必要となります。受け口は Receive アクティビティ、返却口は SendReply アクティビティとなります。これらは個別にデザイナ上にドロップしても構いませんが、大体は面倒なので 1 セットになっている ReceiveAndSendReply アクティビティを利用する事が多いと思います。また必要となる一部の設定を自動で行ってくれますので、できるだけ利用するのが楽だと思います。
Receive アクティビティでは多くのプロパティが公開されているので少々戸惑いますが、今回のように簡易なサービスを利用する場合にはそれほど設定箇所はありません。
- OperationName プロパティ:サービスのメソッド名
- CanCreateInstance プロパティ:リクエスト受信時に新規インスタンスを生成するか
- Content プロパティ:リクエストで受け付ける引数の設定
OperationName にメソッド名を定義し、CanCreateInstance にはチェックをつけておきます。そしてメソッドの引数を定義するために CorrelatesOn プロパティを設定します。プロパティダイアログにボタンが表示されているのでそれをクリックすると、コンテントエディタが表示されます。
このエディタで受け取るリクエストの引数を設定します。メッセージとして設定する場合は単一の値、または WCF で利用される DataContract 属性を付けたクラスを指定します。
そして適当な処理の後では何かしらの値を返却するケースがあります。その場合に SendReply アクティビティを利用します。
Receive アクティビティとプロパティは内容が近いです。こちらで必要なのは返却する内容を Content コレクションプロパティで設定します。
今回は適当に編集した値を一つだけ返却しますのでこのように設定します。なおここでは変数を利用していますので、ワークフローの変数としても定義は行っています。
これでサービスとして提供するワークフロー自体は完成です。xamlx として保存します。もう一つ必要なファイルが IIS 上で動作する際の設定ファイルとなる web.config ですが、今回は WCF における既定の構成を利用しますので、以下の内容をそのまま利用します。
1: <?xml version="1.0" encoding="utf-8" ?>2: <configuration>3: <system.web>4: <compilation debug="true" targetFramework="4.0" />5: </system.web>6: <system.serviceModel>7: <behaviors>8: <serviceBehaviors>9: <behavior>10: <serviceMetadata httpGetEnabled="true"/>11: <serviceDebug includeExceptionDetailInFaults="false"/>12: </behavior>13: </serviceBehaviors>14: </behaviors>15: </system.serviceModel>16: <system.webServer>17: <modules runAllManagedModulesForAllRequests="true"/>18: </system.webServer>19: </configuration>
この 2 つのファイルを IIS 上に用意した仮想フォルダにコピーするだけでワークフローサービスとしては動作します。動作しない場合、ファイアウォールで通信を許可しているか、IIS で利用するアプリケーションプールの設定が .NET4 用になっているか、等を確認してみてください。
今回は動作確認に、WCF テストクライアントを利用しました。
このように通常と殆ど変りのないワークフローな xamlx ファイルを IIS に配置しただけでサービスとして利用できているのがわかると思います。外部公開するサービス、と言われると難しいイメージを覚えられることもあると思いますが、WF4 を利用した場合のサービス公開はこのように非常に簡単なものとなっています。
2011年4月27日水曜日
SQL Server のテーブルを全て CSV 出力するワークフロー
SQL Server でテーブルの内容を CSV 出力する事はそれなりに頻度があるかと思います。大体は BCP 等のユーティリティを利用して行うとか、それをスクリプトにまとめておくとか、そのような形ではないでしょうか。同じことをワークフローでも表現してみました。
今回は次のような流れのワークフローです。
- データベースからテーブル一覧を取得
- テーブルごとにデータを抽出
- 抽出したデータを CSV 出力
テーブル一覧を取得する部分は今回新規に用意したアクティビティですが、それ以外は今までの記事で利用したものとなっています。ロジックはこのような感じです。
1: Imports System.Activities
2:3: Public Class GetSQLTableListActivity4: Inherits AsyncCodeActivity
5:6: Private Const SQL_GETTABLE = "SELECT * FROM SYS.TABLES"7:8: Property ConnectionString As InArgument(Of String)9: Property Condition As String = ""10: Property TableList As OutArgument(Of String())11:12: Public Sub New()13: Me.DisplayName = "SQL Server のテーブル一覧を取得"14: End Sub15:16: Private Delegate Function GetSQLTableListDelegate(ByVal conString As String, ByVal conditionStrings As String) As String()17:18: Protected Overrides Function BeginExecute(ByVal context As System.Activities.AsyncCodeActivityContext, ByVal callback As System.AsyncCallback, ByVal state As Object) As System.IAsyncResult19: Dim conStr = context.GetValue(Me.ConnectionString)20: Dim asyncGetSQLTableListDel = New GetSQLTableListDelegate(AddressOf GetSQLTableList)21: context.UserState = asyncGetSQLTableListDel22:23: Return asyncGetSQLTableListDel.BeginInvoke(conStr, Me.Condition, callback, state)24: End Function25:26: Protected Overrides Sub EndExecute(ByVal context As System.Activities.AsyncCodeActivityContext, ByVal result As System.IAsyncResult)27: Dim asyncGetSQLTableListDel = TryCast(context.UserState, GetSQLTableListDelegate)28: Dim resultStrings = asyncGetSQLTableListDel.EndInvoke(result)
29: TableList.Set(context, resultStrings)
30: End Sub31:32: Private Function GetSQLTableList(ByVal conString As String, ByVal conditionStrings As String) As String()33: Dim result As String()34:35: Dim tabList As New DataSet36: Try
37: Using sqlConn As New SqlClient.SqlConnection(conString)38: sqlConn.Open()39: 'テーブル一覧の取得
40: Dim execSql As String = SQL_GETTABLE41: If conditionStrings.Trim <> "" Then42: execSql += " WHERE name like '%" + conditionStrings + "%'"43: End If44: execSql += " ORDER BY name "
45:46: Dim dataAdapter As New SqlClient.SqlDataAdapter47: dataAdapter.SelectCommand = New SqlClient.SqlCommand(execSql, sqlConn)
48: dataAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey49: dataAdapter.Fill(tabList)50: sqlConn.Close()51: End Using52: Catch ex As Exception53:54: End Try55: '結果を String() に出力
56: If tabList.Tables.Count > 0 Then57: Dim resultList As New List(Of String)58: For Each childRow In tabList.Tables(0).Rows59: resultList.Add(childRow.item("name").ToString)
60: Next
61: result = resultList.ToArray62: Else
63: result = Nothing
64: End If65:66: Return result
67: End Function68:69: End Class
SQL Server では SELECT * FROM SYS.TABLES とすることでテーブル一覧が取得できますので、その結果を今回は String の配列として返却するようにしています。
そうして得たテーブル一覧に対して ForEach アクティビティでループ、その内部では取得したテーブル名を元にデータを取得、その結果を利用して ForEach アクティビティで更にループ、以前利用した CSVOutput なアクティビティを利用して1行ずつファイルへと出力しています。
このようにワークフローとして処理を記述すると、スクリプトやツールの知識がなくとも行われている処理内容が非常にイメージしやすくなります。このあたりが Workflow の醍醐味なのではないか、と個人的には思っています。