ラベル trouble の投稿を表示しています。 すべての投稿を表示
ラベル trouble の投稿を表示しています。 すべての投稿を表示

2012年4月26日木曜日

PHPExcelで使えない数式

PHPExcel(バージョンはちょっと古い1.7.4)でExcel5形式でExcelを書きだす時に、セルに書いても空白になってしまう(罫線すら付かない...)計算式(formula)のメモ。

下記の数式をPHPExcelで使おうとすると、セルに何も出力されないので注意。


SUFIFS()
Excel2007からの数式なので仕方ないんだろう。


SUMPRODUCT()
下記のようにSUMIFSの代わりに使おうとすると空白になる。

=SUMPRODUCT((A1:A5='hoge')*(B1:B5='hage'),C1:C5)


SUMIF()
下記のように条件のところを他のセル値の参照にすると空白になる。
=SUMIF(A1:A5,B1,C1:C5)


空白になるのは、PHPExcelの内部的には数式のパースエラー時にExceptionを投げてて、それをcatchしてそのまま処理を続行してるからみたい。


(おまけ)
&が使えない
「=A1&"@"&B1」と書いたら「=A1」と出力される。
対策としては、下記のようにCONCATENATE()を使えばOK。
=CONCATENATE(A1,"@",B1)

2011年9月29日木曜日

PHPExcelで PDFが文字化けする問題の解決方法


PHPExcelではExcelの他にPDFも出力できる。

$writer = PHPExcel_IOFactory::createWriter($xls, "PDF");
$writer->save($path);
しかし、これだとPDFで日本語を出力しようとすると文字化けする。

文字化けを回避するには、フォントをセットする必要がある。
$writer = PHPExcel_IOFactory::createWriter($xls, "PDF");
$writer->SetFont('arialunicid0-japanese');
$writer->save($path);
これができるようになったのはわりと最近のようだ。(参考:PHPExcel - phpexcel - View Issue #11919: Can't set font on writing PDF

ただし環境によってはこれでも見られないらしい。(参考:PHPExcel の PDF出力で日本語文字化け2 携帯ビューア - PC・通信メモ


また、PHPExcelで作るPDFはExcelとして出力した場合と比べていろいろ違う(罫線とか数値フォーマットとか横幅とか)ので、綺麗に出すにはPDF用にいろいろ工夫しないといけないようだ。


参考

2011年3月31日木曜日

「lexicon (XLLEX.DLL)が見つからないか、または壊れています。」の修復

Windows XPでMS Office 2007のアプリを起動できなくなった問題に対して、試行錯誤した上で何とか回復できたことのメモ。
回り道が多くて余分なこともしてると思うが、誰か(あるいは自分)の役に立つかもしれないので記録しておく。


いつものようにExcelを開こうとすると「lexicon(XLLEX.DLL)が見つからないか、または壊れています。」というエラーメッセージが表示され、Excelが開けない。
また、Wordも開かなくなっている。(開こうとすると何も書かれていなくてOKボタンしかないダイアログが表示される。)
XLLEX.DLLというファイルはOfficeのフォルダにあるので、レジストリがおかしくなっている?

Googleで調べてみたが、Windowsを再インストールするか、あるいはWindowsユーザーを新しく作り直すしか対策が見つからない。(それは嫌だ。)

「プログラムの追加と削除」でOfficeをアンインストールして、OfficeのインストールCDから再インストール。しかし状況変わらず。何回か繰り返したが駄目。

Windowsの「システムの復元」を使って、Excelが開けた頃にWindowsを戻す。

Excelを立ち上げようとすると、これまでとはまた別のエラーが出るようになった。
それに対してOfficeを再インストールしようと試みるも、そもそもアンインストールができない

  • 「プログラムの追加と削除」から「変更」「削除」ボタンを押しても、数秒固まるだけで何も起きない
  • OfficeのインストールCDのSetup.exeを起動すると、インストールエラーが発生して終了してしまう
この状態でインストールしようとしてもエラーになってインストールできない。

Microsoft Office 2007をアンインストール(削除)ができない|星屋工作室で紹介されているMSのサイトの「Fix it で解決する」というのをダウンロードして実行したら、Officeをアンインストールできた。

CDからOfficeを再インストール。

ExcelもWordも使えるようになった!


もしかしたら最初からFix itを使えば解決したのかもしれない。
Office2007だけでなく、2003や2010もアンインストール用の「Fix it」があるようだ → コントロール パネルからアンインストールできない場合、Office 2003、Office 2007 または Office 2010 スイートをアンインストールする方法


また、この後Microsoft UpdateによるOffice2007 SP2のインストールがどうしても失敗する事象が発生。

Office2007のサービスパックが当たらない - りぶろくを参考にWindows Installer 4.5をダウンロードしてインストール

SP2もインストールできた。

2010年11月21日日曜日

PHPで 「Webページの有効期限が切れてます」となる時の傾向と対策

PHPでフォーム等を作った場合、Webブラウザの戻るボタンやJavaScriptのhistory.back()で前のページに戻った時に「Webページの有効期限が切れてます」と表示されることがある。

上記はIEの場合で、ブラウザによって少し挙動が違う(下記)。
いずれもページを更新(リロード)するとサーバにPOSTが再送信され、ページが表示される。
  • IE
    • 上記(IE8の例)のような画面が表示される。
  • Firefox
    • 「このページを表示するにはフォームデータを再度送信する必要があります。フォームデータを再送信すると以前実行した検索、投稿や注文などの処理が繰り返されます。」という確認ダイアログが表示され、「再送信」ボタンと「キャンセル」ボタンが表示される。「再送信ボタン」をクリックするとページが表示される。
  • Chrome
    • 「フォーム再送信の確認
      このウェブページを正しく表示するには、先ほど入力したデータが必要です。データをもう一度送信することは可能ですが、このページで行った操作をすべて繰り返すことになります。データを再送信してこのページを表示する場合は [再読み込み] をクリックしてください。」というメッセージのみの画面が表示される。
  • Safari
    • このようなダイアログが表示される。(Windows版で確認。Mac版は分からない。)



犯人はだれだ?


原因は、PHPでSESSIONを使うと(デフォルト設定では)自動でキャッシュ制御用のHTTPヘッダーが送出され、それによりクライアント側のキャッシュが使用不可にされるため。(参考:floatingdays: PHPでブラウザキャッシュを有効にする

つまり、下記条件を全て満たした場合にこの現象が発生する。
  1. HTTP POSTで遷移してきた。
  2. SESSIONを使っている。(session_start()してるか、php.ini等でsession.auto_start=1に設定している。)
  3. 次のページに行ってから、ブラウザの履歴機能(JavaScriptのhistory.back()を含む)で戻ってきた。



じゃあどうすればいいの?

対策として有名なのは、session_start()する前に、session_cache_limiter('none')とすること。
session_cache_limiter('none');
session_start();
これにより、SESSIONを使っても余計なHTTPヘッダーが送出されなくなる。

または、php.ini等でsession.cache_limiterに"none"を設定しても同じことになる。(おそらく元ネタはこのあたりだろう → PHP: session_cache_limiter - Manual

実際にこれで問題は解決する。



異論反論オブジェクション! [shut very bad!]

しかし、「PHP/「ページの有効期限切れ」対策 - Glamenv-Septzen.net」によると、これはPHPが想定しているパラメータではなく、お行儀のよいやり方ではないらしい。

'none'というパラメータは正しいパラメータではなく、それゆえに何もHTTPヘッダーを送出しないという挙動になるらしい。
(ただし、もし「規定外のパラメータはスルーする」というのが意図した仕様だとしたら、'none'でも何でも「正しいパラメータ」だけど。)

上記の記事ではsession_cache_limiter('none')ではなくsession_cache_limiter('private_no_expire')を推奨している。
「ページの有効期限切れ」をsession_cache_limiter()で解決 - shinyanakaoのよすがブログ」でも同様にprivate_no_expireを推奨している。

しかし、実際にsession_cache_limiter('private_no_expire')を使うと、やはり余分なHTTPヘッダーが送出される。

private_no_expireの場合、(privateに比べて)Expiresが送出されなくなるが、「Cache-Control: max-age=(session.cache_expire ぶんだけ未来)」が送出されるため、やはりブラウザに影響が出てしまう。(参考:現在のキャッシュリミッタを取得または設定する - PHP 5.3 日本語マニュアル
Firefoxでは問題ないが、IEだとリロード時にもキャッシュを使ってしまい、サーバからのリロードができなくなるようだ。(参考:Webアプリケーション開発ラボ by NPO情報活用センター - PHP:キャッシュ問題について。PHP Tips|ワークスポット・ジェーピー
おそらくsession.cache_expireで設定されている期間はキャッシュが有効になるのだろう。(Expiresでそう指定しているのだから、IEは悪くない。)

なので、お行儀が悪くてもsession_cache_limiter('none')を使うしかないのでは?('none'じゃなくて'hoge'でも'hage'でも「正しい」パラメータ以外なら何でもいいけど。)



新たな選択肢

しかし、こういう手もあるよ。
session_start();
header('Expires:'); //下記「余談」の追記も参照
header('Cache-Control:');
header('Pragma:');

header()でセミコロンの右に何も書かないと、PHPは何も送出しないようだ。
これにより、session_start()のHTTPヘッダー送出を上書きし、結果的に何も送出しない。

session_cache_limiter('none')より冗長だが、明示的という意味ではいいかもしれないと思っている。
(キャッシュを有効にしたい場合にも応用が効く。)



余談

上記のようにブラウザキャッシュの無効化を無効化すると、当然ながらSESSIONの最新情報が反映されていないブラウザキャッシュをブラウザが表示してしまうので注意。

(2011/1/7 追記)
IEはキャッシュがあり、かつ、そのキャッシュがExpiresを何も指定されていないと、アドレスバーにURLを直接入力された場合やリダイレクトした場合などにサーバにアクセスせずにキャッシュの方を使ってしまう。(Firefoxはその場合もサーバにアクセスしてくれる。)
ブラウザの履歴機能を使うためにキャッシュはさせたいが、上記の場合にはサーバにアクセスさせたい場合は、Expiresで-1を指定すると良いようだ。
header('Expires: -1');
ログイン管理をする場合などはこれをやっておいた方が良さそう。
(追記終わり)

また、POSTのパラメータに「チケット」(=ワンタイムトークン)を入れることによる二重POST防止を推奨するのは正しい。というか二重POSTを確実に防ぎたいと思ったらこれしかない。


2009年11月6日金曜日

CSSフレームワーク YAMLと Highslide JSは相性が悪い

CSSフレームワークのYAMLとページ内ポップアップライブラリのHighslide JSを併用したら、IEで見た場合のみHighslideの表示がおかしくなった。

参考情報を探したが、ドイツ語しか見つからない...


結局解決していない?


具体的には、2カラムの右側(div#col3)にあるリンクをクリックしたらHighslideがポップアップするようにしたら、IEの場合だけ"Loading"の表示が画面の右の方にずれてしまう
場合によっては画面の外にまでずれてしまい、その時だけ横スクロールバーが出るような状況に。

Firebug Liteなどを使って調べていたら、どうやらLoadingのCSSプロパティleftの値がおかしいらしい。
Highslideは、Loadingの位置を計算で求めている。
その際に、offsetLeftを積み上げてleftを計算する。積み上げるというのはリンクからoffsetParentをたどっていき、そのoffsetLeftの合計を求める。(scrollLeftの考慮もしている。)
で、このoffset系のプロパティは、ブラウザによって挙動が違うらしい。

実際にlinkのleftの計算に使われるoffsetParentとoffsetLeftを表示させてみると、Firefox(3.5)とIE(7)ではかなり内容が違う。
まずFirefoxの方はたどるoffsetParentが少ない。すぐにBodyにたどりつく。offsetに関連しない要素は無視するようだ。
対してIEはoffsetに関連しない要素も全部拾う。何が関連するかの判断もFirefoxとはかなり違う。
さらに、IEではdiv#col3の子要素のoffsetLeftの値がおかしい
具体的には、div#col3の子要素は、正しいoffsetLeftの値に加えて、なぜかdiv#col3のoffsetLeftの値が加算されている。
これにより、LoadingのLeftがdiv#col3のoffsetLeft分だけ右にずれてしまうようだ。

ここで、上記の参考サイトを見て、div#col3のpositionプロパティを変えたらなんとなかるかなあと思い実験。
FirefoxのFirebugで調べたところ、div#col3はpositionを指定していないので、デフォルトのstaticのはず。
が、IEでFirebug Liteで調べたところ、なぜかrelativeになっている。IE用のパッチのCSSの影響?
そこで、div#col3のpositionにstaticを指定したら、Loadingがリンクと同じ位置に表示されるようになった。
(たぶん)position:staticの場合、offsetParentの対象でなくなるようだ。これにより、div#col3のoffsetLeftが重複して加算されることを回避できた。

2008年8月14日木曜日

Delicious Bookmarksからデータが消えて PCがフリーズする問題の解決方法(追記:解決した!)

FirefoxのアドオンにDelicious Bookmarksというものがある。ショートカットからDeliciousへのPOSTができたりBookmarkをツールバーに表示したりと非常に便利なのだが、バージョンが2.0.95に上がったら壊れてしまった。(ローカルデータが認識できなくなりSyncを繰り返す。CPU負荷も高く、PCが固まる。)

しばらくこのアドオンを無効にしていたが、先ほどこの問題の解決策を見つけた。

It seems that 2.0.95 causes some trouble, but after I delete delicious.rdf file in my firefox profile directory, it seems works well. This is suggested at the forum in yahoo group described above. Worth to try, I guess, if you in trouble.
from Delicious Bookmarks のレビュー :: Firefox Add-ons
(※2008/8/13のXoraさんのレビュー)
Firefoxのプロファイルにあるファイル「delicious.rdf」を削除したら直るとのこと。
試しにやってみたら、確かに直った気がする。しばらく様子を見てみよう。(※追記あり!)

しかしXolaさんも書いているとおり、"And of course we still need a fix release."
Fixした時に今回の解決策(delicious.rdfを2.0.95に合った形にした)のせいでまたインストールし直しとかにならなければよいが。


追記:しばらくしてFirefoxを再起動したら、またSyncし始めちゃったよー

追追記(2008/08/21):
Delicious Bookmarks のレビュー :: Firefox Add-onsの"Work-around for 2.0.95 problems"をやったら解決した。
1) Log out of delicious.
2) Uninstall delicious addon 2.0.95.
3) Quit firefox
4a) Delete this file for XP: C:\Documents and Settings\\Application Data\Mozilla\Firefox\Profiles\.default\delicious.rdf
or
4b) Delete this file for vista: C:\Users\\AppData\Roaming\Mozilla\Firefox\Profiles\.default\delicious.rdf
5) Restart firefox and install delicious addon version 2.0.64

2.0.64は2つ前のバージョン。1つ前までは試してみたが、2つ前まで戻さなくちゃいけないとは。
今のところこれで以前のように動いている。
Deliciousからの新バージョンについての反応がまだ無いところを見ると、よほど深刻な問題なのか?!

追追追記(2008/08/22): 1つのPCでは解決したが、1つのPCではフリーズっぽくなる...HELP!

ブログ アーカイブ

tags