DataGridとパスワードをつかうためのサンプル
パスワードのマスキングとか
itemRendererにTextInput指定して、displayAsPasswordとかすれば楽っぽいんですけどitemEditorを使う方法で...。
- labelFunctionのマスキング用の関数を指定
- itemEditorにPasswordEditor.mxmlみたいなコンポーネントを指定してあげること。TextInputのdisplayAsPassword="true"は必須で
はまりどころしては、PasswordEditor.mxmlなどでtextプロパティなどで値をセットしておかないと、いつの間にか値そのものが"*****"になってしまう点。ソースコードは、昨日のhttp://d.hatena.ne.jp/shogo4405/20090510/1241957645のソースに追加
PasswordEditor.mxml
<?xml version="1.0"?> <mx:TextInput displayAsPassword="true" xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:creationComplete> <![CDATA[ text = data.name; ]]> </mx:creationComplete> </mx:TextInput>
Main.mxml
<?xml version="1.0"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*"> <mx:Script> <![CDATA[ import mx.controls.*; import mx.collections.*; import mx.controls.dataGridClasses.DataGridColumn; public function getSexname(item:Object, column:DataGridColumn):String { var type:Number = item.sex; return (type == 0) ? "女性" : "男性"; }; // マスキング用の関数 public function masking(item:Object, column:DataGridColumn):String{ return new Array(item.name.length + 1).join("*"); }; public function debug():void { trace(list.getItemAt(0).sex); trace(list.getItemAt(0).name); }; [Bindable] public var list:ArrayCollection = new ArrayCollection( [ { no:1, name:"Taro", sex: 1 }, { no:2, name:"Hanako", name:"Hanako", sex: 0 } ] ); ]]> </mx:Script> <mx:DataGrid width="100%" height="100%" dataProvider="{list}" editable="true"> <mx:columns> <mx:DataGridColumn dataField="no" editable="false" /> <mx:DataGridColumn dataField="name" labelFunction="{masking}" itemEditor="PasswordEditor" /> <mx:DataGridColumn dataField="sex" labelFunction="{getSexname}" editorDataField="value" itemEditor="SexEditor" /> </mx:columns> </mx:DataGrid> <mx:Button click="debug();" /> </mx:Application>
そもそも
そもそもDataGridでパスワード編集させる仕様にするなよ!っていう突っ込みは無です。
DataGridとComboBoxつかうためのサンプル
DataGridの選択エリアにComboBoxを使おうと思って試行錯誤したときのメモ。知らないと難しい...
何も考えないで実装するとこう
以下のようなソースのときに、"sex"カラムが、持っている値は 0 or 1だけど、男性・女性とComboBoxで編集できるようにすることがゴール。
<?xml version="1.0"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ import mx.controls.*; import mx.collections.*; [Bindable] public var list:ArrayCollection = new ArrayCollection( [ { no:1, name:"Taro", sex: 1 }, { no:2, name:"Hanako", name:"Hanako", sex: 0 } ] ); ]]> </mx:Script> <mx:DataGrid width="100%" height="100%" dataProvider="{list}"> <mx:columns> <mx:DataGridColumn dataField="no" /> <mx:DataGridColumn dataField="name" /> <mx:DataGridColumn dataField="sex" /> </mx:columns> </mx:DataGrid> </mx:Application>
labelFunctionを使ってみる
labelFunctionを使うことによって、0→女性。1→男性のようにlabel表記を処理することができます。
<?xml version="1.0"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*"> <mx:Script> <![CDATA[ import mx.controls.*; import mx.collections.*; import mx.controls.dataGridClasses.DataGridColumn; public function getSexname(item:Object, column:DataGridColumn):String { var type:Number = item.sex; return (type == 0) ? "女性" : "男性"; }; [Bindable] public var list:ArrayCollection = new ArrayCollection( [ { no:1, name:"Taro", sex: 1 }, { no:2, name:"Hanako", name:"Hanako", sex: 0 } ] ); ]]> </mx:Script> <mx:DataGrid width="100%" height="100%" dataProvider="{list}" editable="true"> <mx:columns> <mx:DataGridColumn dataField="no" editable="false" /> <mx:DataGridColumn dataField="name" editable="false" /> <mx:DataGridColumn dataField="sex" labelFunction="{getSexname}" /> </mx:columns> </mx:DataGrid> </mx:Application>
itemEditorを使う
で、最後に。itemEditorを使っています。itemRendererを使う方法もあるんがけどそれは置いておきます...。 editorDataField="value"と、itemEditorに自作のmxmlを置いているのがポイントでしょうか...。
main.mxml
<?xml version="1.0"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*"> <mx:Script> <![CDATA[ import mx.controls.*; import mx.collections.*; import mx.controls.dataGridClasses.DataGridColumn; public function getSexname(item:Object, column:DataGridColumn):String { var type:Number = item.sex; return (type == 0) ? "女性" : "男性"; }; [Bindable] public var list:ArrayCollection = new ArrayCollection( [ { no:1, name:"Taro", sex: 1 }, { no:2, name:"Hanako", name:"Hanako", sex: 0 } ] ); ]]> </mx:Script> <mx:DataGrid width="100%" height="100%" dataProvider="{list}" editable="true"> <mx:columns> <mx:DataGridColumn dataField="no" editable="false" /> <mx:DataGridColumn dataField="name" editable="false" /> <mx:DataGridColumn dataField="sex" labelFunction="{getSexname}" editorDataField="value" itemEditor="SexEditor" /> </mx:columns> </mx:DataGrid> </mx:Application>
SexEditor.mxml
編集できるようにitemEditorにカスタマイズした、ComboBoxを指定します。
<?xml version="1.0"?> <mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml"> <!-- creationCompleteでComboBoxの初期値を設定しています。 --> <mx:creationComplete> <![CDATA[ for(var i:int=0, f:int=dataProvider.length; i<f; i++) { if(dataProvider[i].data == data.sex) { selectedIndex = i; break; }; }; ]]> </mx:creationComplete> <mx:dataProvider> <mx:Array> <mx:Object data="0" label="女性" /> <mx:Object data="1" label="男性" /> </mx:Array> </mx:dataProvider> </mx:ComboBox>
あと、Object#dataではなく、Object#fooを使う場合
dataProviderの値にdataではなく、fooを使う場合のソースコードは次の通りです。SexEditor.mxmlのみ変更で対応。
<?xml version="1.0"?> <mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ public override function get value():Object{ return selectedItem.foo; }; ]]> </mx:Script> <mx:creationComplete> <![CDATA[ for(var i:int=0, f:int=dataProvider.length; i<f; i++) { if(dataProvider[i].foo == data.sex) { selectedIndex = i; break; }; }; ]]> </mx:creationComplete> <mx:dataProvider> <mx:Array> <mx:Object foo="0" label="女性" /> <mx:Object foo="1" label="男性" /> </mx:Array> </mx:dataProvider> </mx:ComboBox>
Amazon.co.jpでまとめ買いをしたいという欲求で...
こんなものつくってみました
Amazon.co.jpでコミックスのまとめ買いをしたいという欲求で、FlexとAmazonのAPIを利用してつくってみました。検索してドラッグアンドドロップでショッピングカートに突っ込んで、Amazon.co.jpで購入をクリックでAmazonでものが買えます。
気づいたけど
自身の本のまとめ時間の短縮目的で制作したんですが…トータル時間的にはこのアプリをつくっている時間のほうが長い…(--;というわけで、皆さんのまとめ買いの購入時間の短縮につながれば幸いです。
サイトのURL
PEAR-SOAPとFlexからの通信(サーバサイド)
PEAR-SOAPを用いて作られたWebServiceをFlexからSOAP通信で呼び出したときのメモです。色々とはまりどころがあったのでその際のメモも一緒に。
サンプルつくるにあたっては、サーバ側(PHP)→クライアント側(Flex)の順番で作成しています。
1.サーバ側の準備
サーバ側に必要なのは、実際のSOAP通信の際に受け口になってくるphp(xml.php)で、今回はメソッドなどを外出ししたかったので、クラスにまとめました(Service.php)。
サーバ側のソースなどは以下の通りで、簡単の為にxml.phpとService.phpをサーバのドキュメントルートに設置しています。http://localhost/xml.phpでアクセスできるようにしています。
xml.php
<?php require_once 'Service.php'; require_once 'SOAP/Server.php'; $server = new SOAP_Server(); $server->addObjectMap(new Service(), "urn:foo"); // ※1 if(isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST') { // $server->service($HTTP_RAW_POST_DATA); $server->service(file_get_contents('php://stdin')); // ※2 } else { require_once 'SOAP/Disco.php'; $disco = new SOAP_DISCO_Server($server, 'foo'); header("Content-type: text/xml"); if(isset($_SERVER['QUERY_STRING']) && strcasecmp($_SERVER['QUERY_STRING'], 'wsdl') == 0) { echo $disco->getWSDL(); } else { echo $disco->getDISCO(); } exit; }
Service.php
<?php class Service { public function __construct() { $this->__dispatch_map = array(); $this->__dispatch_map['hello'] = array( 'in' => array('arg' => 'string'), 'out' => array('return' => 'string') ); } public function hello($string) { return $string; } }
WSDLの表示
ここまでつくってhttp://localhost/xml.php?wsdlにアクセスすると以下のようにWSDLが表示されればOK!!!
Application.InputBoxでセルが選択できない件
散布図にラベルを追加するマクロ - Thousand Yearsでセルを"A4"とか直接入力しないといけないのめんどくさい。Application.InputBox(Type:=8)とした場合はエクセルのセルをクリックしてセル名を自動挿入してくれる仕様なのだけれども、自分が書いたコードはそうなっていなかった。原因を調べたらApplication.ScreenUpdatingの順番だったので訂正。
セル選択ができない版
' スクリーンの更新をOFF Application.ScreenUpdating = False ' ラベル開始セルの指定 If (labels Is Nothing) Then On Error Resume Next Set labels = Application.InputBox(Prompt:="ラベル開始セル名を入力してください。例)A1", Type:=8) If (Err.Number <> 0) Then Exit Function End If On Error GoTo 0 End If
セル選択ができる版
' ラベル開始セルの指定 If (labels Is Nothing) Then On Error Resume Next Set labels = Application.InputBox(Prompt:="ラベル開始セル名を入力してください。例)A1", Type:=8) If (Err.Number <> 0) Then Exit Function End If On Error GoTo 0 End If ' スクリーンの更新をOFF Application.ScreenUpdating = False
そうなんですね...。
散布図にラベルを追加するマクロ
散布図のポイントにラベルを追加したい
Excelで散布図をかいたときにポイントにラベルを追加したいんですがなかなかうまくいかないので思い悩んだあげくVBAで解決したので、その際のスクリプトをかいたので公開しておきます。
方法を調べていったら、斜めにデータを配置するのがオーソドックスなやりかたみたいですね。ttp://pc.nikkeibp.co.jp/article/NPC/20060628/242035/
使い方と前提条件
マクロ実行時に「セル名を入力を促すダイアログ」が出てきますが、そのときはラベル名の一番最初のセル名を入力してください。この例では、B3を指定するとラベルが自動的に振られます。条件としてテーブルのフォーマットはサンプルのような{ラベル名,X,Y},{ラベル名,Y,X}とかそういう表を前提としています。
ソースコード*1
Public Sub 散布図にラベルを追加する() AttachLabelsToPoint End Sub Private Function AttachLabelsToPoint(Optional labels As range = Nothing) Dim i As Integer, j As Integer If (ActiveChart Is Nothing) Then MsgBox ("アクティブなグラフはありません。" & Chr(10) & Chr(13) & "ラベルを追加するグラフを選んでください。") Exit Function End If ' ラベル開始セルの指定 If (labels Is Nothing) Then On Error Resume Next Set labels = Application.InputBox(Prompt:="ラベル開始セル名を入力してください。例)A1", Type:=8) If (Err.Number <> 0) Then Exit Function End If On Error GoTo 0 End If ' スクリーンの更新をOFF Application.ScreenUpdating = False ' ラベルの記入処理 For i = 1 To ActiveChart.SeriesCollection.Count For j = 1 To ActiveChart.SeriesCollection(i).points.Count ActiveChart.SeriesCollection(i).points(j).HasDataLabel = True ActiveChart.SeriesCollection(i).points(j).DataLabel.Text = labels.Offset(j - 1, 0).Value Next j Next i End Function
追記
- スクリプト修正:セルが選択ない件を修正
*1:にわかVBAerなので突っ込み歓迎
漢数字をアラビア数字に変換とか(突貫工事)
漢数字をアラビア数字に
一か八かとか、万が一。百子(人命)とか機械的に変換してしまわないように、一桁の数字は排除して漢数字をアラビア数字に変換するプログラム。突貫工事。
(JSで実装したんだけど欲しいのはPerlのプログラム...。)
ソース
"フランス料理のコース二千五百円(サービス料金加えて三千円)三名様より".toArabiaSuuji(); // "フランス料理のコース2500円(サービス料金加えて3000円)三名様より"
(function() { var base = {"零":0, "一":1,"二":2,"三":3,"四":4,"五":5,"六":6,"七":7,"八":8,"九":9}; var mult = {"十":10, "拾":10, "百":100, "千":1000,"万":10000,"億":100000,"兆":1000000}; String.prototype.toArabiaSuuji = function() { var i, ch, stack = [], inner = false, buf = this.split(''); for(i=buf.length;0<=i;i--) { if(inner) { ch = mult[buf[i]]; if(ch) { stack.push('+', ch); buf[i] = ''; continue; }; ch = base[buf[i]]; if(ch) { stack.push('*', ch); buf[i] = ''; continue; }; if(stack.length) { buf[i+1] = eval(stack.join('')); stack = []; }; inner = false; } else { ch = mult[buf[i]]; if(ch) { stack.push(ch); ch = base[buf[i+1]]; if(ch) { stack = [ch, '+'].concat(stack); buf[i+1] = ''; }; buf[i] = '', inner = true; continue; }; }; }; if(stack.length) { buf[0] = eval(stack.join("")); }; return buf.join(''); }; })();
ToDo
- バグつぶし。(一億五千万円とかまったく出来ない)
- リファクタリング
追記
一億五千万円とかまったく出来ないでのやり直し。