スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
拍手コメントを見る

ExcelのSDI化の落とし穴

以前に書いたExcelを別ウィンドウ(SDI)で開く。Win7編という記事に拍手+コメントを頂きました。
頂いたのですが、どこにも公開されることの無いコメントなので(たぶん)、返事のしようが無く、ここに新しく記事を書くことにしました。
※FC2の拍手コメント機能ってどう使えば効果的なのかさっぱり判っておりません。

さて、別ウィンドウでExcelを開けて万々歳!と思っていたのですが、ひとつ不便なことがありました。
それは、ブック間(ファイル間)のシートのコピーや移動ができないことです。
ブックAのシートAAをブックBにコピーしたり、移動したり、が、別ウィンドウで開いたExcelブックだと出来ないんですね。
ひとつのExcelで複数のブックを開いてあげると、移動もコピーもできるので、臨機応変に使い分けていただけるとよろしいかと存じます。
スポンサーサイト
拍手コメントを見る

テーマ : Windows
ジャンル : コンピュータ

tag : Excel 別ウィンドウ SDI Win7

Excelを別ウィンドウ(SDI)で開く。Win7編

Windows7 と Office 10 の Excel ですが、やはり1つのウィンドウ内に複数のファイルを持たせるMDI方式です。
あれとこれを目視で比較しながら…という場合にMDIは不向きのため、SDI形式にしたいのです。

↓このように別ウィンドウだと比較しやすくなる場合があります。
SDIのデモ


Windows XP の場合は、エクスプローラーから設定できたのですが、Vista ではレジストリの変更で対応できました。(→過去記事はこちら
Widnows7はどうかというと、Vistaと同じく、レジストリの変更しかないようです。

というわけで、その方法です。

  1. regedit を起動します。
    →[Win Key] + [R] を押して、"regedit"と入力してエンター。

  2. HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Excel.Sheet.12\shell に移動します。

  3. shellを右クリックしてメニューから[新規 - キー]を選択します。

  4. 新しいキーに適当な名前を付けます。ここでは"SDI"としています。

  5. [SDI]を選択して、右ペインの"(既定)"をダブルクリックし、値のデータに"SDIで開く(&S)"と入力し、[OK]をクリックします。

  6. 左ペインの[SDI]を右クリックし、メニューから[新規 - キー]を選択します。

  7. 新しいキー名を "command" とします。

  8. [SDI - commmand]を選択して、右ペインの"(既定)"をダブルクリックし、値のデータに次の1行を入力します。
    "C:\Program Files (x86)\Microsoft Office\Office14\EXCEL.EXE" "%1" /dde
    ↑この場所にexcel.exeがあることが前提です。/dde 以外はダブルクォートで囲む事をお忘れなく。


この設定で、エクスプローラーから *.xlsx ファイルを右クリックすると"SDIで開く(&S)"メニューが増えています。
追加したSDIのメニュー

旧ファイル形式の *.xls ファイルも対象とするには、
HKEY_LOCLA_MACHINE\SOFTWARE\Classes\Excel.Sheet.8\shell に移動して手順3と同じことをします。

*.csv ファイルも対象とするには、
HKEY_LOCLA_MACHINE\SOFTWARE\Classes\Excel.CSV\shell にも同じことをします。

なお、デフォルトで SDI として開きたい場合、[shell] の"(既定)"の値を"SDI"にします。
こうすることで、ファイルのダブルクリックでそれぞれ別ウィンドウで開いてくれるようになります。 拍手コメントを見る

テーマ : ソフトウェア
ジャンル : コンピュータ

tag : Excel 別ウィンドウ SDI Win7

AnimatedGIF をコントロールに貼り付けて放っておくとCPUを食いつぶす件

いやぁ、久々にブログ書きます。twitterばかりでしたから。
たまには長文って思っていたりしたんですが、根が面倒くさがりなので。

さて、本題です。

先日、AnimatedGIFが張り付いたコントロールを表示して放置しておいたら、CPU使用率が徐々に上がっていく現象が起こりました。
以前はそんなこと無かったよな?と思いつつ、起きるときと起きないときの違いがわかりました。

起きない方は .NET1.1 で作られて、
起きる方は .NET2.0 で作られている

という事がわかりました。
.NET 3.0 ならどうなん?ということで試してみたのですが、やっぱりCPUが食いつぶされていきます。

さぁて、困りました。どうしましょ?
.NET2.0以降を利用する上では、このままでは連続稼働させることができなくなってしまいます。

回避方法はないものかいなと思案していたところ、ある方から ImageAnimator クラスは使えないだろうか?というヒントを頂きました。
へぇ、ほぉ。

というわけで、利用方法を調べつつ実装してみました。
001:// アニメーションGIFの確認
002:private Bitmap mMyImage = new Bitmap(GetType(), "MyAnimatedGIF.GIF");
003:private bool mIsAnimated = false;
004:
005://
006:// イメージ貼り付け先コントロール(lblX)のPaintイベントハンドラを実装
007://
008:private void lblX_Paint(object sender, PaintEventArgs e)
009:{
010: if (ImageAnimator.CanAnimate(mMyImage))
011: {
012: // アニメーション可能なイメージなら、フレームを1つ進める
013: ImangeAnimator.UpdateFrames();
014: }
015: e.Graphics.DrawImage(this.mMyImage, new Point(0,0));
016:}
017:
018://
019:// アニメーション処理をスタートしたいとき呼んでね
020://
021:public void StartAnimation()
022:{
023: if (this.mIsAnimated) return;
024:
025: if (ImageAnimator.CanAnimate(mMyImage))
026: {
027: // アニメーション可能なイメージなら、開始依頼
028: // onImageFrameChanged イベントハンドラオブジェクトに処理依頼
029: ImangeAnimator.Animate(this.mMyImage, new EventHandler(onImageFrameChanged));
030: this.mIsAnimated = true;
031: }
032:}
033:
034://
035:// アニメーション処理をストップしたいときに呼んでね
036://
037:public void StopAnimation()
038:{
039: if (ImageAnimator.CanAnimate(mMyImage))
040: {
041: // アニメーション可能なイメージなら、終了依頼
042: // onImageFrameChanged イベントハンドラオブジェクトに処理依頼
043: ImangeAnimator.StopAnimate(this.mMyImage, new EventHandler(onImageFrameChanged));
044: }
045: this.mIsAnimated = false;
046:}
047:
048://
049:// アニメーションに関する処理を行うイベントハンドラ
050://
051:private void onImageFrameChanged(object sender, EventArgs e)
052:{
053: // イメージ貼り付け先のコントロール(lblX)の再描画依頼(lblX_Paint呼び出し)
054: this.lblX.Invalidate();
055:}

適当なユーザーコントロール(またはフォーム)に、lblX という名前のLabelコントロールがあることを想定しています。また、歴史的背景からAnimatedGIFの貼り付け先は、PictureBoxではなくLabelを使っています。

で、結果ですが、CPUのバカ食いは解消されました。
.NET1.1 を利用する上では、上のコードは一切不要ですが、.NET2.0以降は考慮が必要となってきます。

ちなみに、
029:        ImangeAnimator.Animate(this.mMyImage, new EventHandler(onImageFrameChanged));
:
043: ImangeAnimator.StopAnimate(this.mMyImage, new EventHandler(onImageFrameChanged));

は、
029:        ImangeAnimator.Animate(this.mMyImage, onImageFrameChanged);
:
043: ImangeAnimator.StopAnimate(this.mMyImage, onImageFrameChanged);

でもコンパイルは可能ですが、CPU使用率はぐんぐん上がっていきます。
イベントハンドラオブジェクトに処理させる必要があるため、new EventHandler(...)とやっているんですね。

・・・いまいち理解できてませんけど。 拍手コメントを見る

テーマ : プログラミング
ジャンル : コンピュータ

TortoiseSVN で複数の bugtraq を利用する方法

TortoiseSVNbugtraq は、コミットログにバグ追跡システムとの連携を関連付ける機能として非常に便利です。Notes/Domino を利用した構築方法は、過去のこの記事に書いてあります。
ただし、Version 1.6.6 現在に至るまで、複数のバグ追跡システム等への連携はとれません。

例えば、運用面か何かで、バグ追跡システムのサーバー引越しなどが発生し、引越し先では新たに発見した問題以降が登録されたとしたら、これまでのコミットログに記述した課題番号付きログが無用の長物になりかねません。

こりゃ、困ることになるな、と少々頭をひねってみました。

通常は、bugtraq:url にバグ追跡システムの URL とともに、文書を特定するための %BUGID% を記述します。%BUGID% は変数扱いで、コミットログに入力した文書IDが代入されます。
ユーザーはコミットログに付加された文書IDをクリックすれば、目的の文書が存在する URL に TortoiseSVN が変換してくれて、ブラウザで表示できるというわけです。

簡単に書くと、こんな感じ。

TortoiseSVN -> バグ追跡システムの該当文書

そーか。bugtraq:url に直接バグ追跡システムのURLを記述するから運用規模が狭くなっているのだ!と気が付いて、次のような事を思いつきました。

bugtraqPortal.html (仮称)を間にかませて、bugtraqPortal.html にて目的の url を分岐させてみてはどーでっしゃろ!?

簡単に書くと、こんな感じ。

TortoiseSVN -> bugtraqPortal.html (どのシステムを利用するか判断)
--> Aのバグ追跡システムの該当文書
--> Bのバグ追跡システムの該当文書

結論からいうと、出来ました。

これをうまく利用すれば、一方はバグ追跡で、もう一方は仕様文書へのリンクなどコミットログに貼りつけるといったような運用が可能になります。

詳細を書く前に、決め事があります。
文書IDの書式を特定しておきます。

例えば通常利用している文書ID(チケットIDとも言う)の書式が XXXX-YYYYYY だとします。
X には、大文字のアルファベットのみが入り、
Y には、大文字のアルファベットと数字が入ります。
正規表現で書けば、次のようになります。
X は [A-Z]{4}
Y は [A-Z0-9]{6}

こいつに細工をします。コミットログに文書IDを記載するときに、



XXXX-YYYYYY
-Zn
↑ ↑
文書ID システム識別子



のように、"-Zn" といった suffix をつける方向で話を進めます。
言うまでもなく、追加した "Zn" が、今回の bugtraqPortal.html に通知して「どのシステム利用するか」を特定させるための識別子です。

なお、過去のコミットログには、XXXX-YYYYYY が存在することも考慮して、"-Zn" が付かないケースも想定しておきます。
ですので、%BUGID% 変数には、既存の "XXXX-YYYYYY" または、今回拡張した "XXXX-YYYYYY-Zn" が入ってくる事になります。

TortoiseSVN の属性 bugtraq:url には、次のように指定します。ただし、後述の html が正しく動くか確認してからの作業になるので、実際には最後に行います。

bugtraq:url http://hoge/bugtraqPortal.html?%BUGID%

コミットログに記載された、"XXXX-YYYYYY(-Zn)" を特定するために、bugtraq:logregx の指定も必要です。こちらも、後述の html が正しく動くか確認してからの最後の最後の作業になります。

1行目:[A-Z]{4}-[A-Z0-9]{6}(-Z[0-9]+)*
2行目:([A-Z]{4}-[A-Z0-9]{6}(-Z[0-9]+)*)

※今回はコミットログ中のどこに、"XXXX-YYYYYY(-Zn)" が現れてもリンクをはらせたいので、1行目と2行目はほぼ同じです。

では、キモとなる %BUGID% を受け取る側の bugtraqPortal.html の中身です。

受け取った引数(%BUGID%)を分岐判断させ、目的の文書にリダイレクトさせるために、JavaScript を利用しました。


<html>
<head>
<title>bugtraq portal</title>
<script type="text/javascript">
<--
// デフォルトのurl
var url='http://issues/current/';

// URLの引数部分 '?' 以降を取り出し、一時変数 arg に代入します。
var arg = location.search;

// 引数の変数部分の文字列を取り出し、arg に再代入します。
arg = arg.substring(1,arg.length);

// arg から 文書ID部分のみを取り出し、一時変数 docID に代入します。"
// "XXXX-YYYYYY" 部分なので、index = 0 から 11文字分となります。

var docID = arg.substring(0,11);

// arg から分岐先の識別子 "Zn" を取り出し、一時変数 urlID に代入します。
// "Zn" 部分なので、13文字目以降を利用します。index は0から開始なので注意

var urlID=arg.substring(12);

// 分岐処理
switch(urlID)
{
case 'Z0':
url = 'http://issues/backup_000/';
break;
case 'Z1':
url = 'http://issues/backup_001/';
break;
default:
// 箸にも棒にも引っかからないケース
//url = url;
break;
}

// リダイレクト
setTimeout("link()",0);
function link() {
location.href = url + '?id=' + docID;
}
-->
</script>
</head>
</html>


この bugtraqPortal.html を http サーバーに保存しておきます。

TortoiseSVN の属性である、bugtraq:url と bugtraq:logregx を前述の方法で指定登録して利用します。

例)
コミットログに、"XXXX-YYYYYY-Z1" が書き込まれれば、リンクを自動作成し、そのリンクをクリックすると、
http://hoge/bugtraqPortal.html?XXXX-YYYYYY-Z1 が呼び出され、
呼び出された bugtraqPortal.html は次のURLにリダイレクトします。
http://issues/backup_001/?id=XXXX-YYYYYY 拍手コメントを見る

テーマ : ソフトウェア開発
ジャンル : コンピュータ

tag : TortoiseSVN bugtraq

DoCoMo ユーザーに教えてもらった au の機能

au の EZ Web のお気に入りリスト画面。
そこから左ソフトキーで「ショートカット」というのがあります。
ショートカット画面の1番に「お気に入り」のどれかを登録します。

ショートカットの画面で、1番を選択して実行!
・・・なにも起こりません。

ショートカットの画面で、1キーを押下!
・・・なにも起こりません。

いったいぜんたい、このショートカットキーってなんざんす?

という不満を口に出したところ、DoCoMo ユーザーから、

「どこかのサイトを開いている状態で、ショートカットの番号キーを長押ししてみてください。」

おぉぉぉぉお!
知らなかった!取説なんて開いた事ないからねぇ。

ありがとう、DoCoMo ユーザーの人! 拍手コメントを見る
ブログ内検索
プロフィール

雷ぶ

Author:雷ぶ

最近の記事
最近のコメント
最近のトラックバック
カテゴリー
月間アーカイブ
ブロとも申請フォーム

この人とブロともになる

RSSフィード
リンク

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。