SSブログ
エクセル ブログトップ
前の5件 | -

エクセルのちょっといい話(22):エクセル2013以降の不都合緩和 [エクセル]

エクセルのちょっといい話(20):エクセル2003の並列実行」で触れたように、直近エクセルを含むエクセル2013以降では、シートを開く度に表示位置がずれて行くという問題があります。

また、マルチスレッド計算(マルチコア演算)を有効にしていると、複雑で重い処理を行うブックではオーバーヘッドが発生し、処理が著しく遅くなったり、場合によってはハングアップしてしまうことが少なからずあります。

こららの問題は、エクセルの設定を変えれば何とかなると言ったものではなく、ブック毎に対処する必要があります。
なお、マルチスレッド計算に関しては、エクセルの設定で無効化することができますが、使用環境によっては解除後に再び有効にしておく必要があり、面倒です。

KFシステムクリエイター及びそれに関する一連のツールにおいては、基本的に全てのブックでマルチスレッド計算を無効化しています。一方、システムに関係ないブックでは、マルチスレッド計算を有効にしています。
これらを上手く使い分けるためには、各ブックのマクロベースで対処する必要があります。

VBAには、マルチスレッド計算を制御するMultiThreadedCalculationというオブジェクトがあります。これをThisWorkBookモジュールに記述することで、ブックオープン時にマルチスレッド計算を無効化し、ブッククローズ時に再び有効にすることができます。

また、ブック(ウインドウ)の表示位置を制御するには、Application.Top及びApplication.Leftというプロパティを使えば可能となります。
これらは表示位置の取得の他に、表示位置の指定にも使用できます。

これらを用いてエクセル2013(マルチスレッド計算についてはエクセル2007)以降で生じる不都合を緩和することができます。
その概要は、次の通りです。


1.標準モジュールでの型宣言

この宣言はシートモジュールに対しても行うため、Publicを用いる必要があります。項目はブックの上位置、ブックの左位置、エクセルのバージョンの3つです。

2.ThisWorkBookモジュールでの起動処理、終了処理

ブックのオープン時に、開いたブックの上位置、同左位置、エクセルバージョンを取得します。更に、バージョンがエクセル2007以降の場合は、マルチスレッド計算を無効化します。
ブックのクローズ前には、マルチスレッド計算を有効に戻します。

3.シートモジュールや標準モジュールでの処理

ブックから他のブックを開く処理がある場合、ブックを開いた直後にそのブックの上位置と左位置を、元ブックの位置に揃えます。
なお、元ブックの位置がずれた場合に備え、上記ブックオープン前に、念のため元ブックの上位置と左位置を再取得しておきます。


これらの処理により、例えばブック上に記載したファイル名をダブルクリックすると、そのブックが開くといったマクロでは、エクセル2010以前と同様に、開いたブックの位置は元ブックに重なるようになります。

また、複雑な処理を行うブックを開く際には、再計算につまづくことが減り、スムーズな処理が期待できます。
もちろん、マルチスレッド計算に適したブックもあり、それらにとっては逆効果となるかもしれません。まあ、ケースバイケースといったところでしょうか。

nice!(0)  コメント(0) 
共通テーマ:

エクセルのちょっといい話(21):エクセル2003の導入 [エクセル]

私は現在でも、KFシステムクリエイターの開発、及びそれを用いたシステム設計には、Microsoftエクセル2003を用いています。
Microsoft365による最新版エクセル(直近バージョン)も所有していますが、システムの互換性と安全性の確認用として利用しているのみです。

私がエクセル2003を使い続けるのは、処理の軽さと互換性の高さのためです。基本的に、エクセル2003で作成したシステムは、以降のバージョンのエクセル(32bit版)でも、マクロを含めて問題なく動作します。

ただし、マクロ実行中に表示が乱れたり、ブックの多重オープン時に表示位置がずれたりするといった問題はありますが、これは直近バージョンの仕様によるものであり、エクセル2003で作成したことが原因という訳ではありません。

エクセル2003では、直近バージョンと比較して、関数や命令の種類がやや少ない、ワークシートの大きさや数に制限がある、等のデメリットもありますが、それらを考慮した設計を行えば、以降のバージョンでも基本的には互換性が保たれます。

また、リソース不足の問題もありますが、これは基本的に32bit版エクセル全般の話であり、直近バージョンでも本質的な違いはありません。
なお、Windowsの設定で、クリップボードの履歴を有効にしておくと、リソースが極端に減少する場合があるので、注意が必要です。

制限の多さは、逆に処理の軽さにもつながるため、エクセル2003では以降のバージョンと比較して、2割程度の処理速度向上が図れます。
わずか2割ではありますが、これは例えば最適化演算等の重い処理を行う場合、5時間掛かるところが4時間で済むことになり、数字以上に大きな効果となります。

さて、そのエクセル2003ですが、当然現在では新規に入手することは出来ません。ただし、抜け道はあります。それは、メルカリなどのフリマサイトや、ヤフオク等のオークションサイトを利用する、ということです。
ただし、グレーゾーンの出品も目立ちますので、注意が必要です。一番安心なのは、パッケージ版を購入することでしょう。

エクセル2003のインストールと認証は、指示に従って進めれば、通常は問題なく行われます。ただし、ボリュームライセンス品等の場合は、認証が通らない場合があるようです。
また、インストールの途中で、エラー1919等により処理が中断する場合がありますが、「無視」を選択すれば、最後までインストールすることが出来ます。

こうしてエクセル2003を導入したとしても、そのまますぐに使えるわけではありません。多くの場合、初期エディションのままとなっていますので、それをサービスパック3(SP3)に更新する必要があります。

以前であれば、自動更新でSP3が適用されたのですが、現在では自動更新は出来ないようです。そのため、手動で更新してやる必要があります。
更新ファイルは、「MicrosoftUpdate カタログ」サイトから入手できますが、cabで圧縮されたmspファイルでの提供となりますので、導入のハードルはやや高いかもしれません。

導入するには、最初にダウンロードしたcabファイルを展開します。これは、ダウンロードしたファイルをダブルクリックし、表示されたmspファイルを右クリックして"展開"を選び、展開先フォルダを指定すれば実行できます。

次に、展開して得られたmspファイルをダブルクリックすれば、Windowsインストーラが起動して、インストールが実行されます。
なお、これらがよく分からない場合は、ネットを探せば実行ファイル形式のインストーラが見つかるかもしれません。

ちなみに、同ファイルの名前は"Office2003SP3-KB923618-FullFile-JPN.exe"となっていますので、これでググればヒットすると思います。
なお、安全でないサイトからの実行形式ファイルのダウンロード及び実行には、ウイルス感染等の危険がありますので、必ずウイルスチェックを行う必要があります。

システムの開発や設計だけなら、以上でエクセル2003を使用できるようになりますが、直近バージョンでの確認や、配布、使用を必要とする場合、エクセル2007以降で採用されたxlsxやxlsm、xlsbなどのファイル形式を扱えた方が便利です。

そのための機能として、2018年までエクセルコンバータ(Microsoft Office 互換機能パック)が提供されていましたが、現在は入手できなくなっています。
上述した「MicrosoftUpdate カタログ」サイトでも見つかりませんでした。

ただし、"FileFormatConverters.exe"で検索すれば、非公式のダウンロードサイトがいくつか見つかるかと思います。
必要な方は、充分なウイルス対策を行った上で試してみてください。

実は、このエクセルコンバータは、その後も更新されており、「MicrosoftUpdate カタログ」に"Microsoft Office 互換機能パック Service Pack 3(SP3)"として掲載されています。サポート技術情報番号はKB2526297です。

この対象製品はOffice2007となっていますが、エクセルコンバータを適用したエクセル2003にも適用可能です。
エクセルコンバータを導入したら、必ずこのSP3も適用するようにしてください。なお、実行形式ファイルは"compatibilitypacksp3-kb2526297-fullfile-ja-jp.exe"ですが、ググれば見つかるかもしれません。

以上、現行環境においてエクセル2003を導入する方法について、説明いたしました。現行のWindows10においては、問題なく使用できるものと思いますが、今秋リリース予定のWindows11については、インストール可能かどうか分かりません。

もっとも、私の貧弱なハード環境では、Windows11へのアップグレードは絶望的な為、私自身への影響は全くありません。
今後、Windows11への移行を考えている方にとっては、エクセル2003の導入に際しては十分注意する必要があります。

nice!(1)  コメント(0) 
共通テーマ:

エクセルのちょっといい話(20):エクセル2003の並列実行 [エクセル]

KFシステムクリエイターの管理ツールであるKFシステムコントローラには、複数のエクセルを同時に起動し、それぞれのエクセルで開いたブックのマクロを個々に実行する「並列実行ツール」が内包されています。
これは、Core i5などのマルチコアCPU環境でシステムを運用する場合に有用です。

KFシステムクリエイターは極めて複雑なシート構成となっているため、マルチコアを有効にしたエクセルで実行すると、頻繁にオーバーヘッドが発生し、処理が著しく停滞したり、場合によってはハングアップしてしまうことがあります。
そのため、システムの実行環境としては、マルチコアやマルチスレッドを解除することを推奨しています。

しかし、そうすると当然のことながら、マルチコアCPU環境であっても一つのコアしか使用することが出来ません。例えば4コアCPUの場合では、CPU使用率は最大で25%程度にしかならないわけです。
そこで、エクセルを別インスタンス(プロセス)で4つ同時に起動し、それぞれで異なる処理を行わせることで、CPUの実効使用率を100%ほどに高めることが出来るようになります。

本来であれば、エクセルの標準的な機能としてマルチタスクが実現できればいいのですが、残念ながら仕様上、シングルタスクによる逐次処理しか出来ません。
そのために、複数のブックに分かれた重い処理を並列・同時に行うためには、別インスタンスで複数のエクセルを起動し、それぞれで処理を行ってやる必要があるわけです。

それを実現するために、並列実行ツールでは、「エクセルを起動して指定ブックを開きマクロを実行させる」、という一連の操作をVBSファイルで書き起こし、それを複数同時実行させることで、"疑似的"に並列処理を実現しています。

この処理では負荷の調整や配分が出来ないため、事前に各処理に掛かる時間を見計らって、各インスタンスに出来るだけ均等になるよう実行ファイルを配分してやる必要があります。
そのため、あくまで"疑似的"な並列処理(マルチタスク)となっています。

本来のマルチタスクであれば、先に処理が終わって待ちが生じているインスタンスに対し、他のインスタンスで処理待ちのファイルがあれば、それを割り当てることが出来るはずなのですが、本並列実行ツールでは残念ながらそれは出来ません。それゆえに、"疑似的"ということになります。

しかし、KFシステムクリエイターにおいて最も処理が重い時系列分析においては、各処理に掛かる時間が長いため、基本的には処理待ちが生じる余裕はありません。
そのために、"疑似的"な並列実行ツールであっても、その効果が損なわれることはほとんどありません。

従来は、エクセルにおいて並列処理を行うためには、このようなVBSを介しての"疑似的"な方法しかありませんでした。私が最初にシステムに実装したのは2008年3月のことですから、それ以前も含めてずいぶん長い間、新たな試みはなされていなかったように思います。

しかし、最近になって(といっても2年前ですが)、VBSを介さないでマルチスレッドを実現する方法が、"ことりちゅん"さんによって提案されました。

それは、Application.OnTimeを使用するというものですが、詳細につきましてはご本人のブログをご参照ください。なお、リンクの許可申請をしておりませんので、「ことりちゅん マルチスレッド VBA」でググってみてください。
検索結果上位にある2019年3月27日の記事が、それに該当するかと思います。

さて、今回の記事で紹介したいのは、実はこの新たな方法の事ではありません。少なくともKFシステムクリエイターにおいては、従来のVBSを介した並列処理で速度的な問題はなく、使用上の不便等を感じる場面もありませんでした。

私は専らエクセル2003環境でシステム開発や実行を行ってきたのですが、少なくともその環境においては現在も全く問題はありません。
しかし、Microsoft365(旧Office365)の導入により、状況は一変しました。並列実行ツールで処理を行うと、最新エクセルが同時起動するようになったのです。

もっとも、これは随分以前から分かっていたことであり、従来はエクセル2003の自動修復を実行することにより、エクセル2003を既定アプリとして設定し直していました。
また、並列実行が効力を発揮する時系列分析では、最近まで自動実行ツールが出来ていなかったこともあり、並列実行ツールを使用することがなく、特に不便を感じることはありませんでした。

しかし、最近になってやや重い処理を並列実行ツールで行ったところ、起動したエクセルのシートがずれて重なって表示されることに気が付きました。
それが、各処理毎に生じる訳ですから、画面レイアウトはぐちゃぐちゃで訳が分からなくなり、現在どの処理を行っているのか見当が付きません。

調べてみると、これはエクセル2013以降の仕様であり、従来のMDI(マルチ ドキュメント インターフェイス)からSDI(シングル ドキュメント インターフェイス)に変更されたため、ということが分かりました。
しかも、この仕様は設定等で変更できず、ユーザー側では対処のしようが無いようです。

KFシステムクリエイターにおいては、エクセル上でブックを次々に呼び出して処理を連続して行うことが多いのですが、エクセル2003(正確にはエクセル2010以前)では、同一インスタンス上で開いたブックが全て重なって表示されていたため、表示上の問題はありませんでした。

しかし、エクセル2013以降では、せっかく各インスタンスで最初に起動するエクセルブックの位置を決めてやっても、そこから更に呼び出されるブックの表示位置までは制御できなくなってしまいました。
もちろん、各ブックのマクロに、表示位置を決める命令を書き込んでおけば良いのかもしれませんが、使用環境によっては却って面倒な事になる可能性があります。

元々、システムの実行環境としてはエクセル2003が最も適していることから、それがインストールされている環境では、強制的にエクセル2003を起動することを考えました。
具体的には、最初に並列実行ツールを起動したエクセルのバージョンが2003であれば、同ツールから起動されるエクセルもまた2003とする、と言うことです。

もちろん、エクセル2003がインストールされていない環境や、並列実行ツールを起動したエクセルのバージョンが2003以外の場合は、従来通りの処理を行うものとします。
その際、ブックがずれて表示されるという症状は解消しませんが、最終的な処理結果に影響を与えるものではありません。

一番手っ取り早いのは、前述した通りエクセル2003上でアプリケーションの自動修復を実行する、というものです。
しかし、Microsoft365を使用している場合、かなり頻繁に再修復が行われて、既定アプリが最新エクセルに変更されるという問題があります。

並列実行ツールでは、Excel.Applicationオブジェクトを生成してエクセルを起動していますが、この場合、既定のエクセルしか実行できません。
レジストリの変更でこれを回避するという方法も、ネット上には散見されますが、根幹にかかわる部分をあまり変更したくはありません。

そこで、もう一つ考えられるのが、WScript.Shellオブジェクトを用いるという方法です。これを用いて、エクセル2003を直接実行してやれば、既定に関わらず2003バージョンを開くことが出来ます。
しかし、ここで重大な問題が生じます。この方法だと、エクセルのブックを開くところまでは実行できても、それに含まれるマクロを実行することは出来ない、ということです。

Excel.Applicationを用いる従来の標準的な方法であれば、ブックのオープンやマクロの起動など、エクセルで行う様々な処理を指定することが出来るのですが、WScript.Shellでは各アプリケーションが標準的に持っている機能(引数)しか指定することが出来ません。

そこで、この問題を回避するために、最初に起動するブックに自動実行マクロを含ませることにしました。具体的には、起動専用ブックを並列実行マクロから新たに生成し、そのThisWorkbookモジュールのWorkbook_Openプロシージャに、本来起動したいブックとマクロを記述するという方法です。
合わせて、表示位置や終了処理等も記述してやれば、従来の並列実行ツールと同等の処理が出来ます。

起動したいブックの名称やマクロ名、終了処理等に必要ないくつかの指標については、起動専用ブックのシートに予め記載しておき、ブックのオープン時に参照するようにしています。
マクロを起動専用ブックに付加するには、CodeModuleオブジェクトを使用します。これを行うには、事前にVBEのツールから参照設定を開き、「Microsoft Visual Basic for Applications Extensibility 5.3」を有効にしておく必要がります。

あとは、起動専用ブックのエクセル2003からの実行をVBSファイルに書き出し、並列実行ツールからVBSを実行すれば、目的のブックが複数のエクセル2003から起動し、マクロが実行されます。
・・・となるはずでしたが、実はエクセル2003の起動時に、セキュリティ警告が出てしまうことが分かりました。Excel.Applicationを用いた方法ではこの警告は出ないのですが、WScript.Shellを用いると回避できないようです。

これは、エクセル2003のマクロのセキュリティレベルを"低い"に設定しておけば、回避することが出来ますが、常時この設定にしておくのはさすがに気が引けます。
さりとて、並列実行マクロを起動する度に、セキュリティ設定を手動で変更するのも面倒です。

そこで、やや反則的ですが、レジストリをいじることにしました。といっても、システムを不安定にさせかねない大規模なものではなく、セキュリティのレベルを変更するだけのものです。
そして、起動専用ブックが開き、VBSの処理が終了するタイミングで元に戻します。こうすることで、次回以降のエクセル2003の起動時には、セキュリティレベルは標準の"中"(KFシステムクリエイター推奨設定)に戻っていることになります。

エクセル2003のセキュリティレベル変更には、レジストリの"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\11.0\Excel\Security\Level"の値を設定し直します。
この値が"1"ならセキュリティレベルは"低い"、"2"なら"中"となります。更に、"3"なら"高"、"4"なら"最高"となります。レジストリの書き換えには、WScript.ShellのRegWriteメソッドを用います。

これでようやく、パソコン環境に依存せずにエクセル2003を並列起動出来るようになりました。
なお、レジストリの操作には常に危険が付きまといます。また、安易にセキュリティレベルを下げる行為についても、十分な注意が必要です。

ちなみに、エクセル2003が入手できない場合など、それよりも新しいバージョンのものを使わざるを得なくても、2013以降は表示の問題で使いたくないことがあるかもしれません。
その場合は、エクセル2003の実行ファイルとレジストリの部分を、例えばエクセル2010のものに置き換えてやれば、対応可能だと思います。

nice!(0)  コメント(0) 
共通テーマ:

エクセルのちょっといい話(18) [エクセル]

エクセルで集計作業を行う際に、複数のシート間の値を串刺し的に集計したい場合があります。
例えば、次図のような日々の集計表内の特定データを、全日付に渡って別シートに一覧化したい時、一体どうすればいいのでしょうか。

200526b.png

もちろん、マクロを使えば簡単ではありますが、それでは芸がありません。そこで、エクセル関数のみで対処できないか、考えてみます。

次図は、集計結果の一例です。実はこのシートでは、直近行をその下の行にコピーして日付を変えるだけで、各データがその日付のシートのデータに変更されます。

200526a.png

以下に、その仕組みについて解説いたします。

シートを横断して集計するためには、通常は次式のように入力します。

 ='シート名'!セル番地 ・・・①

例えば、5月26日のシートのI8セルの値を表示するには、

 ='5月26日'!I8

とすれば良いわけです。

しかしこの方法だと、各数式毎にシート名を入力してやる必要があり大変です。そこで、例えばA列にシート名と同じ日付を入力しておいて、それをシート名の代わりに参照してやることを考えます。
シート名はテキストですから、当然それに対応した形式に変換してやる必要があります。5月26日に対応するA101セルを使用して、次式のようにしてみます。

 =TEXT(A101,"m月d日") ・・・②

結果は期待通り「5月26日」と表示されます。これを①式に代入するわけですが、このままでは上手くいきません。
①式は参照式なのですが、②式はあくまで文字列です。そこで、文字列を参照式に変換してやる必要があります。それにはINDIRECT関数を用います。

 =INDIRECT(TEXT(A101,"m月d日")&"!I8")

ここで、参照先のセル番地を一旦文字列に変換して、それを結合した上で全体を参照式に変換するのがミソです。
これで目的シートの特定セル値を表示することが出来るようになりました。

この数式を、集計用シートに日付毎に並べておけば、あとはシートを追加する毎に対応行をコピーしていくだけで、集計表の更新が出来るようになります。
シート間のデータを自由に横断することにより、2次元から3次元へと分析の幅を広げることが可能になるのです。

nice!(0)  コメント(0) 
共通テーマ:

バグ修正 [エクセル]

ご無沙汰しております。

KFデータマネージャおよび当日データ取得マクロにおいて、単元株数を正常取得できない等の不具合を修正いたしました。
ご必要の方は左記「ダウンロード」リンクよりダウンロードを行ない、ファイルを差し替えてご利用ください。
なお、最新ファイルは「KFデータマネージャ020.xls」および「当日データ取得012.xls」です。

以上

[18:47追記]
「KFデータマネージャ020.xls」に細かな不具合があったため、再修正しました。この時間以前にダウンロードされた方は、お手数ですが再取得願います。

nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:
前の5件 | - エクセル ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。