Perlから切っても切り離せない機能リファレンス。初心者の方には、「参照」やら「構造データ」「コンストラクタ」云々とどっと新しい単語が出てくるので、躊躇しちゃうかもしれない。
しかし、これ使えないと、いつまで経ってもウロウロ状態です。
でも大丈夫、簡単な事なんです。
リファレンスとは単純に「参照」で、その場所を指しているにすぎません。
なので、それが「変数の中身」だったり「サブルーチン」だったり、「リスト」や「ハッシュ」だったりします。他にもまだまだありますよ。
以下を見て下さい。
$james変数には、"I am James Brown."というデータが入ってますね。
この変数のデータが入っている場所を参照、リファレンスする場合です。
$james = "I am James Brown.";
$whereJB = \$james;
このように、単純に「¥」を付けるだけです。リストやハッシュ、サブルーチンも同様です。
すると、この「データの場所」を得ることができる訳です。
ここで重要な事は、「変数名はどうでもいい、ただデータの場所を得る」という事です。
さて、このリファレンスからデータを取ってきたい場合(デリファレンス)はこうします。
ん?これは間違い?いや、こう書くんです。「$$」と$を2つ続けて書きます。
print $$whereJB;
まずは、上をよーく見て覚えてください。「¥」と「$$」ですよ。
正確(分かり易く)には、以下のようになります。混乱しないように。
print ${$whereJP}; スカラー変数として見たい場合
print @{$whereJP}; リスト変数として見たい場合
print %{$whereJP}; ハッシュ変数として見たい場合
print &{$whereJP}; サブルーチンとして見たい場合
このように頭の記号によって、「なにで参照戻し」を行うかを決定します。
肝ですよ、ちゃんと覚えてください。
コードの書き手によって、リファレンスは多様にも化ける事も知っておく必要があります。つまり、なにを指しているリファレンスなのか、知っておく必要がある。
さて?何に使うリファレンス
一番と手軽に使えそうな場面は、サブルーチンとのデータ受け渡しではないでしょうか?
サブルーチンに、沢山のデータを渡したい場合です。
# こんな大量のデータを・・
$datas{
parent=>'hear dryer',
brother=>'X BOX',
sister=>'PlayStation2',
child=>'FamilyComputer',
};
$datas{pricelist} = @Price;
$datas{partyadr} = 'Yamagata Pref, Higashine city';
# 一気に渡せる。
# (場所だけを渡すので素早く渡せる)
$ret = &myroom(\%datas);
sub myroom{
my $present = shift;
....
print %{$present}{sister};
print join('/',@{$present{pricelist}});
....
return $present;
}
ちゃんと理解できたら、知っておくだけのやつ
リファレンスはいろいろなところで機能しています。
グロブなんてのもリファレンス渡しができるので、こんな事もできます。
&write_data(\*STDOUT); # 標準出力グロブを渡す
&
write_data(\*FH); # ファイルハンドルを渡す
Perlでのオブジェクト指向書きにも必須になります。
以下は例(とんでもなく、てきとーなサンプル)
$obj = new test;
print chop $obj->cornhead();
package test;
sub new{bless{}}
sub cornhead{'chophead'}
Perl内部にはシンボルテーブルという空間があって、変数やサブルーチンなどの名前が格納されている。
Perlでは簡単にここにアクセスできる仕組みがあって、コアなプログラムを書くことができる。
"
test"と同じ名前のスカラーとリストとサブルーチン、これらを一つのグロブ変数で参照できてしまう。ハッシュやファイルハンドルも同様。
$test=123;
@test=qw(11 22 33);
sub test{"123123"}
$wonder = *test;
print ${$wonder};
print @{$wonder};
print &{$wonder};
そして、シンボルテーブルは、ただのハッシュとして扱う事ができる。
なので、いかのようにして簡単にアクセスできちゃう。
package sasa; # 唐突にアストロロボササが脳裏に浮かんだので‥
$test1=111;
$test2=222;
$test3=333;
sub test4{die'Help me!'}
$wonder = \%{__PACKAGE__.'::'};
# $wonder = \%sasa::; の方が分かり易いか。
while(($k,$v)=each(%$wonder)){
print "$k = $v\n";
}
結果
k = *sasa::k
wonder = *sasa::wonder
test1 = *sasa::test1
test4 = *sasa::test4
v = *sasa::v
test3 = *sasa::test3
test2 = *sasa::test2
ハッシュの中身はそのままグロブなので、デリファレンスすればいい。
極めてないので、どうでもいい記事なんですが、以下のようなどうでもいいベンチをとってみました。どういうものかというと、サブルーチンへ引数渡しとグローバル変数による参照で、どっちが速いねん・・とだ。くだらね。
結果は、わずか10万回の繰り返しなんだけど、これがグローバル変数の場合の方が2~4ms速い結果が出た。当たり前といえばそうなんだけど、Perlでどうしても速度を追求したいぃとかいう方は、敬遠しがちな広域変数はどうだろう・・use strictをとっぱらってみんな裸になろう!hehe
use Benchmark;
$bn=new Benchmark;
@a=qw(11 22 33 44 55 66 77 88);
sub test{
print @a;
}
for($i=0;$i<100000;$i++){
&
test(@a)
}
print timestr(timediff(new Benchmark,$bn));
いまのところPerl5.8が最新版です。多文字コード圏の日本人として嬉しい多言語サポートがされている。しかし、5.6から始まったUnicodeでも同じ5.8でも5.8.2と5.8.3では対象規格微妙に違ったりする。
以前に沢山お世話になったjcode.plのような使い方ができないのかなぁとかいう方が多いと思うので参考になれば。
以前はソースコードにEUC-JPを使うことが無難として重宝がられてましたが、これからはUTF8がいいかも。ということで、ここではソースコードがUnicode(UTF8)の場合で説明。
大事なのは必ずuse utf8プラグマを設定する事(BOMは付けても付けなくもいい。ない方が無難だな)
覚えるのはこれだけだ。
「データを入れる時はdecode、出すときはencodeと覚える。」
これだけでいい。
use utf8;
use Encode;
# 入力:Shift-jisのファイルをゲットする
open(FH,"i_am_sjis.txt")||die;
while(<FH>){
push @a,decode("shiftjis",$_);
}
# 入力:UTF8のファイルをゲットする
open(FH,"i_am_utf8.txt")||die;
while(<FH>){
push @a,decode("utf8",$v);
}
# 出力:Shift-jisで出す
print encode("shiftjis","ゴルバチョフ\n");
# 出力:Shift-jisでファイル出す
open(FH,">we_a_sjis.txt")||die;
foreach(@a){
print FH encode("shiftjis",$_)."\n";
}
close FH; |
PerlによるUnicodeの扱いの肝となるのが、「デカ文字フラグ*1」というもの。この文字列は、UnicodeなのかOLDなものなのかを判断するもので、常にこれを意識しながらプログラミングしないといけないのだ。
英語圏の人は「1バイト(8ビット)=1文字」の誤りに気づき、日本語や中国語のように「複数バイト=1文字」がクールな事を認識したらしい。JIS、シフトJIS、EUC-JP、EBCDIC、DEF云々と日本プログラマの日々の涙ぐましい努力のお陰でここまでこれたのだ。
しかしながら、まだUnicodeの普及は完全ではないし、これまでの資産はかなりのもの、Perlとしてはこの「デカ文字フラグ」で対処して、これは新しいやつ、これは古いやつ・・として扱い、あらゆる入力、あらゆる出力に、デカ文字フラグをONしてOFFして、エンコードを噛ますことになる。そして、必要なら漢字コード変換もやる。
案の定、Perlコードで使いたいデータは必ずフラグをONにしてから使う。コード内で使わないのであれば、フラグ関係無しに利用してもいい(単純にデータを流すだけとかね)
「ウオ~~~~!」
「!面倒じゃーいい」テーブルをひっくり返す前に。あなたはCJK文化圏に属するものとして、運命(さだめ)なのです。従う他ない。
*1思いっきり造語です。>UTFフラグ
なので、これからのPerlは、
encode フラグを外す
decode フラグを付ける
で覚える。それだけだ:-)
なので、以下のコードは、「え?おかしくない?」とか思ってしまう。だが"江頭の静と動"と$gyaraは違う結果になってる。上記説明のように、内容は同じでもフラグがONかOFFかで相違しているという事だ。
(UTF8でかかれたコード。文字列"江頭の静と動"はUTF8コード)
$gyara = encode("utf8","江頭の静と動")
Unicodeかどうかを調べる。
utf8::is_utf8("....")
個別に漢字変換する場合(フラグが付いてないもの)
Encode::from_to($moji,'shiftjis', 'euc-jp');
ちなみに漢字コード名は、エイリアス・別名定義がされているので、Shift-jisでもshiftjisでもいい。
PerlIOレイヤーというものが完備され、変換処理がさらに奥深くなった。
その都度、encodeするのではなく、自動でやってもらう場合は以下のようにすると、入出力にShift-jisを使うことになり自動で処理される。
binmode(STDOUT,":encoding(shiftjis)");
binmode(STDIN,":encoding(shiftjis)");
binmode(STDERR,":encoding(shiftjis)");
ただし見ての通りファイルの入出力には効かないので、徹底したい方は以下も書いちゃうと良い。
(あまりお薦めしないけどね・・)
use open IO => ":encoding(euc-jp)";
基本的にはその都度OPENで拡張された構文で以下のように書く。
open(FH,"<:encoding(shiftjis)","shortjis.txt") or die;
こういった機能は混乱の元となるので、最後の手段として覚えておいた方がいいかも。
古いモジュールが動かない・・とかね。
ま、Unicode規格それ自体への問題はまだ解決されていないが、政治的面倒な事はお偉い方に任せて、われら庶民はコードをせっせと書きませう。
職場から貴方へ・・!
自分が持っているものや、立読み(をい)での大レビューを‥‥2004/2/29
プログラミングPerl 第3版 VOLUME 1 5300 756p
http://www.oreilly.co.jp/BOOK/pperl3v1/
プログラミングPerl 第3版 VOLUME 2 4700 680p
http://www.oreilly.co.jp/BOOK/pperl3v2/
この本は、Perlに触れる者にとって必須の2冊です。あるところでは聖書扱い、別のところでは、Perl税とも言われる位に。:-P
表紙がラクダなので、通称「ラクダ本」と言われる。
(詳しくは「青ラクダ本」「赤ラクダ本」は初版ものを指す)
修行以前の方は、別の「はじめてのPerl」があるのでまずそちらを先に。
Perlに初めて触れた時は単純にCGIを作るの1点だったので、Perlでシステム管理したり、ちょいちょいとデータ加工したりするつもりは毛頭無かった。一応、C言語やJava、VBなど他のプログラム言語を知っているので必要が無かった訳です。
なので、こういったリファレンス本を購入する事もなく、しばらく他のコードを見ながら独学で覚えていきました。案の定、いろいろなところがずっぽりと抜けてる訳で、ある時は「動いているからいいや」的な場面にも出くわしてました。
時は過ぎ、仕事でPerlをいじる場面が出てき始めます。こうなると、「動いているからいいや」じゃ済まされません‥。:-P Perlにはオライリーから出版されている本がいいらしいとの話を良く聞いていたので、調べてみると・・「ガクガク、ナなんて分厚くて高いんだ」こんな厚い本を見るのは、小学生の頃の百科事典の時以来・・かも。しかも、5000円オーバーの書物。しか~も、2部(冊)構成!
まったくの独学だった自分にとって、理解に難しい内容ばかりでした。なんとも恥ずかしく、Perlの一部分しか知らなかった事に気付きました。
なんとかこのモヤモヤ感を払拭するべく、ちょっと高いんですが購入する事に決定。
ここで、やっと‥、はじめてPerlの「本」道に入りました。
Perlの生みの親ラリーウォールさん直々の本らしく、世界に名だたる技術屋さんの人柄も見えてきて読んでて面白い(逆にそれが気になって読むのがストップしてしまう事もあるが)
いろいろなところに散りばめられているロードオブザリング単語が、近頃の流行と相まって‥‥、余計に、気になる。
至る所に哲学めいた言葉が目につく。「Perlは自由」「好きに書け」という事。その高い理想からか暗黙的にプログラマに制限を与えているJavaやC/C++などに比べ、多様な書き方・やり方が述べられています。ネット上にPerlで書かれた作品が膨大に公開されている事もこれに関係があるのかもしれません(モジュールだって手軽に公開できる)
内容は、2冊構成で、合計1436ページの巨大書物になってる。案の定、値段も(計ったかのように)合わせて1万円だ(本国ではいくらなんだ~!)
変数や関数、オブジェクト、リファレンスなどなど、作者が気の済むまで思いっきり深く掘り下げて書いてあります。なので、一度だけで理解するのは難しいと思います。何度も繰り返し読む事で理解を深めることができます。つまり、最初は、章の頭部分だけをなぞらえて読んでいくスタイルがベストかも。
あるいは、(あなたがある程度Perlを知っているなら)興味のある章だけを中心に、深くゆっくりと読み進めていくスタイルもいいだろう。ただ、この場合は、ノートパソコンなどが横にあって、いつでもコードをテストできる環境があるのが望ましい。:-) あとはコーヒーと煙草だね(私は禁煙中だが)
この本を完全に読破するのは難しい、もしかすると1年、いや2年、いや、出来ないかもしれない。だが、この本が机の上に置いてあるというだけで、かなりのステータスになる。1000ページに及ぶドデカイ書物がある訳だ。床が抜けないようにせねば。
という事もあって、この本だけは新品で、しかも誰の手にも触れられていない状態で調達すべき。ブック専門のネット通販がいい。そう、「誰も立ち読みしていない」からだ。まさに工場出荷状態で家に届く。:-) 値が値だけに、送料もタダになるしね。
Perlという仕様があまりに単純に見える、いやそれこそが複雑にしている。それとも哲学か?
この謎を解いてください。
このレビューを参考にしていただけたら、幸いです。中つ国Perlにようこそ!。
Perlトリビア
真珠も英語でパールといい、スペルはPEARL。
ある程度Perlが体に染みてきたら、以下の本をお薦めする。
Perlの理解をもっと深めることができる。★は5段階。
Perlクックブック - Perlの鉄人が贈るレシピ集
5800 816p
http://www.oreilly.co.jp/BOOK/pcook/
かなりお薦め。膨大なコードとチップが掲載される。
★★★★★
入門 Perl DBI
400p 3800
http://www.oreilly.co.jp/BOOK/perldbi/
データベースをいじるなら見ておいて損はしません。どちらにせよコードを見ることがベストですけどね。DBI系はネットにも情報が沢山あるので併用するのがベスト。
★★★★
Perl & XML
3200 244p
http://www.oreilly.co.jp/BOOK/perlxml/
手軽な内容だが、ネットにあまり情報がないXML関連なだけにXMLをいじるのであれば重要な情報です。
★★
詳説 正規表現 第2版
5400 464p
http://www.oreilly.co.jp/BOOK/regex2/
深めるととことん仙人の領域まで行ってしまう正規表現。普段書いているコードに限界を感じてきたら良いかも。Perlに限らず、いろいろなところで使えるからね。
★★★
実用 Perlプログラミング
4500 512p
http://www.oreilly.co.jp/BOOK/adperl/
この本は「プログラミングPerl」を1冊にまとめた本と言っていいかもしれません。ですが、同紙のニッチ(隙間)記事があったり、さらに深く書いてあったりと、やはり同じく、理解を深めるために購入する本と言えるかもしれません。
★★★
CGIプログラミング 第2版
4000 520p
http://www.oreilly.co.jp/BOOK/cgi2/
中身はちょっと古めの内容かも。ただそれも、枯れた(良い意味です)技術であるが故です。独学で無く本当のCGI技術を覚えておきたい方に。
★★★
初めてのPerl 第3版
3600 408p
http://www.oreilly.co.jp/BOOK/lperl3/
Perlの初心者はここから入ってください。基本の基本を学べます。Perlは他の言語に比べて、歴史が深くいまだ広い分野で使われている唯一の言語です。CGIだけでなく、いろいろな事に使えます。この前私はExcel同士のデータ変換にPerlを使いました。至極簡単です。
★★★★
初めてのPerl Win32システム
348p 3200
http://www.oreilly.co.jp/BOOK/lperl32/
「初めてのPerl」参考
★★★
※Win32に特化した内容。お金に余裕があるなら…
続・初めてのPerl - Perlオブジェクト、リファレンス、モジュール
2900 253p
「初めてのPerl」の追加分という形で出版。「プログラミングPerl」を購入するか、より安いこの本でいくか難しいところ。
★★
入門 Perl/Tk
3800 440p
http://www.oreilly.co.jp/BOOK/lperltk/
★
Perl5 デスクトップリファレンス 第3版
96 1200
http://www.oreilly.co.jp/BOOK/p5dkr3/
★★
Perlによるシステム管理
4800 5200p
http://www.oreilly.co.jp/BOOK/perlsysad/
★★
CGI&Perlポケットリファレンス Pocket reference
1980 463p
PerlによるCGIプログラミングに最適なリファレンス本。片手で簡単に開くことができるサイズで、使い勝手においてかなり有効。必要な情報と少しのサンプルが記載されていて、うまいことこのサイズに収まったなと正直思う。安いし、お薦め。
★★★★★
Perlを256倍使うための本 DBI編
1200 255p
世界的にも珍しいコアなDBI本である。DBIを作ってしまえ的な記事はこれしか無い。価格的に安いし、256倍とはいかないまでも‥面白い内容です。
★★★
はじめてのPerlモジュール―厳選実用モジュール集
2500 335p
モジュールについて書かれた本はあまり無く貴重な情報。だが、さらっと書いてあるだけで、思いの外参考にならなかったりする。結局のところ気になってperldocしちゃうとか。Perl初心者の方には、標準モジュールの知識やスタンダードな外部モジュールを知る術を与えてくれる。TkやGD、ソケット(今は標準)などの使い方は貴重だ。
★★
Perlデバッグ明快技法
3800 488p
Perlは手軽な言語なだけに突然のバグ出現に慌ててしまう。残念な事に立派なIDE環境がないので、大規模なPerl開発にはデバッガが最重要。バグの発生しにくいコードの書き方をはじめ、Perlに内蔵している強力なデバッグ機能の解説。この話題に関してはこの本位しかない。
★★★★
Perlデバッグ
2600 235p
こんなデバッグ本もあるらしい。あまり本屋さんで見かけないので、調査中です。
(調査中)
Perl/CGI逆引き大全555の極意
2500 181p
見た目に分厚いのだが181ページしかない。極意という割にはさっぱりとした内容で、分かり易くいうとPerlのさっぱり風ごった煮かな(なんのこっちゃ)よほどの初心者でない限りは、お薦めできない。かさばるし、内容はすぐネットで見つかるようなものです。GD.pmの使い方は有効かもしれません。
★
Perlデータマンジング―データ加工のテクニック集
3200 307p
PerlというとCGIばかりが表に出るが、その名の通り(P_e_r_lは略してそうなってる)テキスト加工(レポート編集)言語がスタートなのだ。データをいかに効率的に変換・活用・管理するか具体的に記述している。Perlのもう一つの一面を見ることができます。
★★★
CGI&Perl究極のレシピ350―とほほが教える
2580 335p
知る人と知る「とほほ」さんが書かれた本。とほほさんのウェブサイトにはかなりお世話になってました。要所を的確に説明しているので、CGI/Perlを始めたい方にはかなり有効です。すでにウェブサイト上でも文書を公開管理しているので、必然的に十分にこなれた内容ですし、お薦めです。
★★★
シェル&Perl入門―bash/tcsh/grep/sed/awk/Perl UNIX & Information Science
2950 268p
Perlは、UNIXではすでに標準ツールとして確たる地位があります。案の定、Perlを覚えればシェル上での強力なツールとして威力を発揮します。あなたがUNIXシステム管理者になりそうだったらお薦めです。
★★ |
やっとこのモジュールを使う機会が訪れたので、参考になればとコードを公開します。
でも、ただのデータ抽出&作成をやるだけなので、いつもの事ながらコードは汚いし、設計&見直も皆無です。ちょちょいで作れるPerlスクリプティングの手軽さっすね。
(あまりPerlのOLE関連のページが無かったので、裾のが広がればと、恥ずかしながら)
Perl5.8/UTF8で書いてます。WindowsのDOS窓で利用しました。なので、ShiftJisで入出力してます。
以前に、WSH/VBA/OLE関連で遊んでてその知識をそのまま生かすことができた。この辺はマイクロソフトの罠っぽいが、せっかくのスキルが無駄にならないのは、なかなかいいねぇ。
予想通りオブジェクトの固まりなので、->がなにかの呪文のようにコードに湧き出ます。
ついつい"."と書いてしまいますが、見た感じはやはり"."の方がスマートな感じ・・がするのは自分だけじゃないですよね。
Excel-OLEオブジェクトの取得
$excel = Win32::OLE->GetActiveObject('Excel.Application')||die'D*mn!';
ブックオブジェクトの取得(ファイル)
my $book = $excel->Workbooks->Open(encode('shiftjis',"C:\\test.exl"))||die'Show the Smile :-)!'
ワークシートオブジェクトの取得
my $sheet = $book->Worksheets(encode('shiftjis','担当者別売り上げ'))||die'S*n of The B*tch';
ここまで書いたら、あとは、PerlというよりVBAやOLE関連の情報を参考にプログラムする事になる。ほとんど一緒。
注意する事は、日本語はちゃんとShiftJisで渡すように心がける事だ。
Excelに関していえば、Rangeオブジェクト周りを押さえておけばいい。マイクロソフトのMSDN辺りで文書を探せばいいかもね。
これがあれば、PerlからWindows関連のソフトを操作できちゃうので、かなり応用できますね。自動化ならかなりもってこい(WSHでできるじゃん。をい)じゃないかー。普段使いなれたPerlで、かゆーいところを掻いてもらえる便利なモジュールでした。
# funk Excel-OLE/Perl code.
# Perl5.8 / utf8 / windows(shiftjis)
require 5.8.0;
use utf8;
use encoding "shiftjis";
use Encode;
use Win32::OLE qw(in with);
use Win32::OLE::Const 'Microsoft Excel';
$|=1;
# OLEオブジェクト取得
my $excel = Win32::OLE->GetActiveObject('Excel.Application')
|| Win32::OLE->new('Excel.Application', 'Quit');
# 担当者
my %tanto;
my $tanbook = $excel->Workbooks->Open(encode("shiftjis","C:\\dev-test\\メーカー.xls"))||die;
my $sheet = $tanbook->Worksheets(encode("shiftjis",'Sheet1'))||die;
$rng=$sheet->Range("A1")->CurrentRegion||die;
for($lp=1;$lp<$rng->End(xlDown)->Row;$lp++){
my $vcd = $sheet->Range("A1")->Offset($lp,0)->{Value};
last if $vcd!~/^\d+$/; # コードじゃなかったら終了
my $vnm = $sheet->Range("A1")->Offset($lp,1)->{Value};
my $vse = $sheet->Range("A1")->Offset($lp,2)->{Value};
next if $vse eq'';
print"$vcd $vnm $vse"."\n";
$tanto{$vcd}=[$vnm,$vse];
}
$tanbook->Close;
# 仕入データ
my $book = $excel->Workbooks->Open("C:\\dev-test\\siire.xls")||die;
# アラート表示回避
$excel->{DisplayAlerts}=false;
# 対象のワークシート
@wsname=qw(4月 5月 6月 7月 8月 9月 10月 11月 12月);
my $month=0;
my $allrecs=0;
my %sltotal=();
foreach$sheetname(@wsname){
my $sheet = $book->Worksheets(encode("shiftjis",$sheetname))||die;
$rng=$sheet->Range("A3")->CurrentRegion||die;
# $rng=$rng->Offset(2,0);
# テーブル位置
print "シート名 : $sheetname\n";
print "カレント領域 : ".$rng->Address."\n";
print "左端 : ".$rng->End(xlToLeft)->Address."\n";
print "右端 : ".$rng->End(xlToRight)->Address."\n";
print "上端 : ".$rng->End(xlUp)->Address."\n";
print "下端 : ".$rng->End(xlDown)->Address."\n";
# ROW最後行までループ
my $recs=0;
for($lp=0;$lp<$rng->End(xlDown)->Row;$lp++){
my $vcd = $sheet->Range("A3")->Offset($lp,0)->{Value};
last if $vcd!~/^\d+$/; # コードじゃなかったら終了
my $vnm = $sheet->Range("A3")->Offset($lp,1)->{Value};
my $vse = $sheet->Range("A3")->Offset($lp,2)->{Value};
print"[$recs - $allrecs] $vcd $vnm \\$vse"."\n";
$allrecs++;
$recs++;
# 集計
$sltotal{$vcd}[$month]+=$vse;
}
$month++;
}
# ワークシート追加
my @tantolist=qw(渡辺 鈴木 佐藤 山田);
foreach(@tantolist){
my $newsheet = $book->Sheets->Add||die;
$newsheet->{Name} = encode("shiftjis",$_); # 表示名
$newsheet->{CodeName} = encode("shiftjis",$_); # 内部名
$newsheet->Range("A1")->Offset(0,0)->{Value}=encode("shiftjis",$_);
}
# ワークシート作成
# 最後の行に順次追加していくのだが。
# SpecialCellやUseRangeメソッドを使ってもうまい事いかないので原始的に・・
while(($ky,$vl)=each%sltotal){
next if $tanto{$ky}[1] eq'';
my $sheet = $book->Worksheets(encode("shiftjis",$tanto{$ky}[1]))||die;
for($lp=0;;$lp++){
last if !$sheet->Range("A1")->Offset($lp,0)->{Value};
}
$sheet->Range("A1")->Offset($lp,0)->{Value}=$tanto{$ky}[0];
$month=0;
foreach$sel(@$vl){
print "$ky - ".$tanto{$ky}[0].$tanto{$ky}[1]." ( $sel )\n";
$sheet->Range("B1")->Offset($lp,$month)->{Value}=$sel;
$month++;
}
}
# 保存
# アラートが出ないのは表示させないようにしてるから
print "Saving..\n";
$book->SaveAs("C:\\dev-test\\total.xls")||die;
#$book->Save||die; |
お勧めのリンク先
PerlからOLEを使用する
自分はここから入りました。シンプルですが要所をついてます。
http://www5a.biglobe.ne.jp/~n_rieko/perl/ole.htm
perlwin32faq12 - PerlからのOLE使用法
ActiveStateの和訳。Perl OLEとはどんなものなのか分かります。
http://www.att.or.jp/perl/faq/perlwin32faq/perlwin32faq12j.htm
vba - 表計算゛ (Hyo-Kei-Zan) - ぱそ工房ばう
記事が古いがかなり有効なVBA関連文書。
http://kobobau.com/xls/yama/vba/
VB プログラミング言語資料 - SAK Streets
VBAのリファレンス関連ならここがいい。
http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/sak3vb.htm
ExcelVBAへの道
VBA。サンプルコードが沢山あります。
http://www.voicechatjapan.com/excelvba/VBArei2.htm
★ Let's Excel VBA ★
ExcelVBAの初心者ならお薦め。一から学べます。
http://www.sanynet.ne.jp/~awa/excelvba/index.html
Excel(エクセル)学習・KENZO30
Excel自体よく知らない場合はここがいい。
http://homepage1.nifty.com/kenzo30/
CGIで画像を動的に作りたいっす!いっちゃん有名なのが、GDライブラリ。他には、PostscriptやPDFをそのまま出力するなんて芸当も可能だが、普通はGDでやる。
いまは、Windowsにも対応したのでppmパッケージをインストールすれば使えてしまう。
基本的な、線、箱、円、文字を描画でき、それをまとめて、PNGやJPEGで出力できる。他画像を取り込むこともできるので、かなり凝った画像生成も可能。
雰囲気的には、大昔のパソコン内蔵BASICのようなものだ。つまり線を引いて塗る・・といった懐かしい?低レベルな描画機能。文字は、外部でファイルを用意する必要がある(ベクターフォント、漢字など)このGDを底辺に置いた拡張ライブラリは沢山あるので、グラフやプロットなど用途に応じて使い分けよう。
テスト用に書いたやつですが。参考にしてください。
require 5.6.0;
package gdtest;
use strict(vars,subs);
#----------
# use module
use GD;
#----------
# use global
use vars qw($lp $ky $vl $tmp @tmp @rec $x $y $x1 $y1 $x2 $y2 $cnt);
use vars qw($color $white $black $gray $ltgray $red $blue $green $dkgreen $yellow $ltyellow);
use vars qw($im);
#----------
# const
use vars qw($Cwidth $Cheight);
use vars qw($Cgrpbsx $Cgrpbsy $Cgrpwid $Cgrphei);
use vars qw($Cgrpsplitx $Cgrpsplity);
use vars qw($Cgrptxtadvx $Cgrptxtadvy $Cgrptxtadhx $Cgrptxtadhy);
#----------
# debug
use vars qw(@Cgraphdata1 @Cgraphdata2 @Cgraphdata3);
# debug data
@Cgraphdata1=(10,20,30,40,-10,30,50,60,10,20,40);
@Cgraphdata2=(20,60,80,40,20,40,-20,10,60,90,20);
@Cgraphdata3=(50,60,70,60,80,40,10,60,70,80,20);
#----------
# initialize
$Cwidth=320;
$Cheight=160;
$Cgrpbsx=24;
$Cgrpbsy=16;
$Cgrpwid=($Cwidth-48);
$Cgrphei=($Cheight-32);
$Cgrpsplitx=($Cgrpwid/10);
$Cgrpsplity=($Cgrphei/10);
$Cgrptxtadvx=-2;
$Cgrptxtadvy=-2;
$Cgrptxtadhx=-8;
$Cgrptxtadhy=0;
#----------
# main
$im = new GD::Image($Cwidth,$Cheight);
$im->interlaced();
#----------
# alloc color
$white=$im->colorAllocate(255,255,255);
$black=$im->colorAllocate(0,0,0);
$ltgray=$im->colorAllocate(220,220,220);
$gray=$im->colorAllocate(128,128,128);
$red=$im->colorAllocate(255,0,0);
$blue=$im->colorAllocate(0,0,255);
$green=$im->colorAllocate(0,255,0);
$dkgreen=$im->colorAllocate(0,192,0);
$yellow=$im->colorAllocate(255,255,0);
$ltyellow=$im->colorAllocate(255,255,200);
#----------
# base draw
$im->transparent($white);
$im->interlaced('true');
$im->rectangle(0,0,$Cwidth-1,$Cheight-1,$black);
#----------
# base graph
$im->filledRectangle($Cgrpbsx,$Cgrpbsy,$Cgrpbsx+$Cgrpwid,$Cgrpbsy+$Cgrphei,$ltyellow);
# lines
for($lp=0;$lp<$Cgrpwid;$lp+=$Cgrpsplitx){
$x=$Cgrpbsx+$lp;
$im->line($x,$Cgrpbsy,$x,$Cgrpbsy+$Cgrphei,$ltgray);
}
for($lp=0;$lp<$Cgrphei;$lp+=$Cgrpsplity){
$y=$Cgrpbsy+$lp;
$im->line($Cgrpbsx,$y,$Cgrpbsx+$Cgrpwid,$y,$ltgray);
}
$im->rectangle($Cgrpbsx,$Cgrpbsy,$Cgrpbsx+$Cgrpwid,$Cgrpbsy+$Cgrphei,$black);
#----------
# out graph!!
$color=$red;
& og_drawgraph_border(@Cgraphdata1);
$color=$blue;
& og_drawgraph_line(@Cgraphdata2);
$color=$dkgreen;
& og_drawgraph_dash(@Cgraphdata3);
#----------
# text
$cnt=0;
for($lp=0;$lp<$Cgrpwid-1;$lp+=$Cgrpsplitx){
$x=$Cgrpbsx+$lp+($Cgrpsplitx/2)+$Cgrptxtadhx;
$y=$Cgrpbsy+$Cgrphei+$Cgrptxtadhy;
$tmp=sprintf("%2d",$cnt);
$color=$black;&og_drawtext($x,$y,$tmp);
$cnt+=1;
}
$cnt=0;
for($lp=0;$lp<$Cgrphei-1;$lp+=$Cgrpsplity){
$x=$Cgrpbsx-($Cgrpsplitx/2)+$Cgrptxtadvx;
$y=$Cgrpbsy+$lp+($Cgrpsplity/4)+$Cgrptxtadvy;
$tmp=sprintf("%2d",$cnt);
& og_drawtext($x,$y,$tmp);
$cnt+=1;
}
#----------
# end
binmode STDOUT;
print $im->png;
#----------
# draw graph
sub og_drawgraph_border{
my(@rec,$cnt,$lp,$x,$y,$x1,$y1,$x2,$y2);
@rec=@_;
$cnt=0;
for($lp=0;$lp<$Cgrpwid-1;$lp+=$Cgrpsplitx){
# get data
$vl=$rec[$cnt];
# draw
$x=$Cgrpbsx+$lp+($Cgrpsplitx/2);
$y=$Cgrpbsy+$Cgrphei;
$x1=$x-($Cgrpsplitx/8);
$y1=$y-$vl;
$x2=$x+($Cgrpsplitx/8);
$y2=$y;
if($y1<$y2){
$im->filledRectangle($x1+1,$y1+2,$x2+1,$y2,$gray);
$im->filledRectangle($x1,$y1,$x2,$y2,$color);
$im->rectangle($x1,$y1,$x2,$y2,$black);
}else{
$im->filledRectangle($x1+1,$y2,$x2+1,$y1,$gray);
$im->filledRectangle($x1,$y2,$x2,$y1,$color);
$im->rectangle($x1,$y2,$x2,$y1,$black);
}
$cnt+=1;
}
}
sub og_drawgraph_line{
my(@rec,$cnt,$lp,$x,$y,$x1,$y1,$x2,$y2);
@rec=@_;
$cnt=0;
for($lp=0;$lp<$Cgrpwid-1;$lp+=$Cgrpsplitx){
# get data
$vl=$rec[$cnt];
# draw
$x=$Cgrpbsx+$lp+($Cgrpsplitx/2);
$y=$Cgrpbsy+$Cgrphei;
$x2=$x;
$y2=$y-$vl;
if($cnt){
$im->line($x1+1,$y1+1,$x2+1,$y2+1,$gray);
$im->line($x1,$y1,$x2,$y2,$color);
$im->line($x1,$y1+1,$x2,$y2+1,$color);
}
$im->arc($x2,$y2,5,5,0,360,$color);
$x1=$x2;
$y1=$y2;
$cnt+=1;
}
}
sub og_drawgraph_dash{
my(@rec,$cnt,$lp,$x,$y,$x1,$y1,$x2,$y2);
@rec=@_;
$cnt=0;
for($lp=0;$lp<$Cgrpwid-1;$lp+=$Cgrpsplitx){
# get data
$vl=$rec[$cnt];
# draw
$x=$Cgrpbsx+$lp+($Cgrpsplitx/2);
$y=$Cgrpbsy+$Cgrphei;
$x2=$x;
$y2=$y-$vl;
if($cnt){
$im->dashedLine($x1+1,$y1+1,$x2+1,$y2+1,$gray);
$im->dashedLine($x1,$y1,$x2,$y2,$color);
$im->dashedLine($x1,$y1+1,$x2,$y2+1,$color);
}
$im->arc($x2,$y2,5,5,0,360,$color);
$x1=$x2;
$y1=$y2;
$cnt+=1;
}
}
#----------
# draw text
sub og_drawtext{
my($tmp);
$im->string(gdSmallFont,$_[0],$_[1],$_[2],$color);
}
# so-ko
#$im->setPixel(2,2,$black);
#$im->line(4,4,32,64,$black);
#$im->dashedLine(4,4,24,64,$black);
#$im->arc(50,50,95,75,0,360,$blue);
#$im->fill(50,50,$red);
#$im->stringTTF($black,'arial',10,0,60,60,'test');
#gdGiantFont gdLargeFont gdMediumBoldFont gdSmallFont gdTinyFont
# end
|
|