2006年3月アーカイブ

Find の timeout : Firefox

Firefox を使っていてページ内のサーチを行うときの "/" を押してウィンドウ下部に準備される
パージ内検索用のツールバーは(なんていうの?)便利がいいのだけれど、いかんせん
消えてしまうのが早すぎる。
たぶん、ffの開発やってる連中からすれば、「忙しすぎてそんなものが長時間表示されていれば
邪魔で面倒で仕方ない。」のだろうけど、俺のようなとろい人間からすると、
「なくなるのが早すぎて役に立たん。使いもんにならん!!」のだ。

で、腹立ったから長時間表示する方法を適当に試してみた。
about:config で accessibility.typeaheadfind.timeout の値を変えて
ffを再起動すればいいらしい。
単位はミリ秒みたいな様で1秒あたり1,000。1分にしたけりゃ、60000 にして再起動すれば
長めに表示してくれる。

こんなもん debug 用は0.1秒、relase 用は30秒とかでデフォルト値を替えるなりしておいてほしい。

フォームで現在のROW をコピーしてあたらしいROWを用意するコード。
クリップボードを使ったコピペをとりあえず断念したのでBASICによる力任せの作業にした。
ただしまだテキストだけ。イメージの扱いがわからない。

なを、ごく普通のテキストと数値データでは扱いが異なっていた。
普通の文字テキストのフィールドでは、
var(0) = form.getByName("フィールド名").Text と
form.getByName("フィールド名").Text = var(0)  のようにText を対象に操作する。

書式化した(FormattedField)では、
Get するときは var(5) = form.getByName("フィールド名").EffectiveValue のよいうに EffectiveValue を使い、
Set するときは form.getByName("フィールド名").EffectiveValue =  CStr(var(5))  のように 
EffectiveValue  に文字列で戻してやらねばうまくいかなかった。

あとは、
form.getByName("フィールド名").commit() が必要。

コードは長いので続きを見て。
データをプログラムとクリップボードとの間でやり取りしたい。
クリップボードからの取得はなんとなく(見つけて)わかって出来たが、
クリップボードに貼り付けるのがうまくいかん。
とりあえず取得方だけメモする。
Function getClipboardText as  string
  getClipboardText = ""
			
  dim Clipboard as object
  dim Converter as object
  dim Contents as object
  dim Types as object
 
  Clipboard = createUnoService( _
	"com.sun.star.datatransfer.clipboard.SystemClipboard")
  Converter = createUnoService("com.sun.star.script.Converter")

  Contents = Clipboard.getContents()
  Types = Contents.getTransferDataFlavors()
	
  l = LBound(Types)
  u = UBound(Types)
  For i = l To u
    If Types(i).MimeType = "text/plain;charset=utf-16" Then
      getClipboardText = Converter.convertToSimpleType( _
	Contents.getTransferData(Types(i)), com.sun.star.uno.TypeClass.STRING)
      Exit For
    End If
  Next
End Function
カレントドキュメントを保存するマクロらしい。
MS-WORD と OOo の2形式で同時に保存するのか?
sub Save_As_All
rem ----------------------------------------------------------------------
rem define variables
	dim document   as object
	dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
	document   = ThisComponent.CurrentController.Frame
	dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
	dim args1(2) as new com.sun.star.beans.PropertyValue
	args1(0).Name = "URL"
	args1(0).Value = "file:///C:/Path/to/File/Filename.doc"
	args1(1).Name = "FilterName"
	args1(1).Value = "MS Word 97"
	args1(2).Name = "SelectionOnly"
	args1(2).Value = true

	dispatcher.executeDispatch(document, ".uno:SaveAs", "", 0, args1())

rem ----------------------------------------------------------------------
	dim args2(2) as new com.sun.star.beans.PropertyValue
	args2(0).Name = "URL"
	args2(0).Value = "file:///C:/Path/to/File/Filename.odt"
	args2(1).Name = "FilterName"
	args2(1).Value = "writer8"
	args2(2).Name = "SelectionOnly"
	args2(2).Value = true

	dispatcher.executeDispatch(document, ".uno:SaveAs", "", 0, args2())

end sub
Saving as .odt and .doc automatically

主記憶拡張

m-R0010372.jpg
うちのメインマシンはInspiron 8000(Pen3/850MHz)にPC100のメモリ256MBとかなり貧弱。
これで最近 OpenOffice.org2.0 BASE のスタンドアロン・データベースを作っている。

OOo BASE の標準DBMS はHSQLDB でオンメモリのDB。 なのでこれに画像などを入れると
かなりメモリを食うようだ。BASE 以外にも調べ物のためにFireFox と ThunderBird、
AdobeReader7 はほぼ常駐状態。たまにPhotoShop も動かすからメモリスワップが
頻発してただでさえ遅いマシンが、かなり悲惨。

主記憶の増設はここ数年(?)の悲願だったけどなかなか実現しなかった。
理由は毎年のようにHDがぶっ壊れてくれたのでこちらの交換に予算を取られてしまっていたから。
しかしやっと買うことができた。オークションでPC133・256MBモジュールが
@¥4,980x2+送料で1万円少々。店頭価格の半額以下?

メモリのスロットの蓋を開けて128MBモジュールを2枚とも外し256MBモジュールと交換する。
PC133のモジュールがPC100のシステムでちゃんと動くか不安だったけどとりあえず
動いている(規格上は動いて当然らしいけど保証の限りじゃなかったし)。

このマシンは今年で5周年。あと何年動いてくれるかなぁ。買い換える金はねぇしなぁ。
当たれ宝くじ!

(とりあえず取っ払った128MBモジュールはオークションでリサイクルしよう。)

Base に組み込みの HSQLDB を使っている場合に有効な手法。

0) バックアップを取っておく(必須)
1) Baseファイルの拡張子を ".zip" に替える。
2) 解凍する。
3) 解凍でできたフォルダの中にある database フォルダから backup をゴミ箱に捨てる。
4) 解凍でできたフォルダの中身(だけ)を再度 zip 形式にアーカイブする。
5) アーカイブファイルのファイル名を元の Base のファイル名(*.odb) にする。

以上でファイルサイズは約半分になります。
(要:自己責任)

その後テーブルを追加したら、それまでのテーブルがすべて消えた。
(なんか疲れたから寝る)
...
(起きた)
ちょっと考えれば META-INF/manifest.xml を変更しなければいけなかったと判る。
<manifest:file-entry manifest:media-type="" manifest:full-path="database/backup"/>
の行も削除してアカーイブすればよいだけのこと。

話は変わるが、OOo 2.0.2rc4[ja] でフォームを変更してアプリケーションを終了すると落ちる。
データはきちんと残っているので問題ないといえば無いのだが、気分悪い。

先日のフォームの表示では BASE のファイル名が必要だった。
しかしこれではファイル名を変更してしまうとマクロをすべて書き換えなくてはならない。
そんなの嫌だから自分自身(ドキュメント)のファイル名を取得する手順を追加した。
例によって悩んで探して二日かかった。"Function DatabaseName" が今回の成果。
そのうち もう少しスマートに書き直そう。
sub Main
	LoadForm( "商品一覧表")
end sub

sub LoadForm( FormName as string)
	subDisplayForm(DatabaseName,  FormName)
end sub

Function DatabaseName as string
	dim form as object
	form =  ThisComponent.DrawPage.Forms.GetByIndex(0)

	dim connection as object
	connection = form.ActiveConnection

	dim dataSource as object
	dataSource = connection.Parent

	DatabaseName = datasource.name
end function

sub subDisplayForm(sDatabaseName as string, sFormName as string)
	dim mArgs(1) as new com.sun.star.beans.PropertyValue
	dim oForm
	oDatabase = fnGetOpenDatabase(sdatabaseName)
	oConnection = oDatabase.DataSource.getConnection("","")
	mArgs(0).name = "OpenMode"
	mArgs(0).value = "open"
	mArgs(1).name = "ActiveConnection"
	mArgs(1).value = oConnection
	oForm = oDatabase.getFormDocuments.getByName(sFormName)
	oDatabase.getFormDocuments.loadComponentFromURL(sFormName, "_ blank", 0, mArgs())
end sub

function fnGetOpenDatabase(sDatabaseName as string)
	oEnum = StarDesktop.getComponents.createEnumeration
	while oEnum.hasMoreElements
		oPosDB = oEnum.nextElement
		if oPosDB.implementationName = "com.sun.star.comp.dba.ODatabaseDocument" then
			if right(oPosDB.DataSource.name, len(sDatabaseName)) = sDatabaseName then
				fnGetOpenDatabase = oPosDB
				exit function
			end if
		end if
	wend
end function

[03/15 追記]
ショック...。
odb ファイル自身のフォームを呼び出すには sDatabaseName を空に("")すればよかった。
したがってこの日の作業はたった1行でよかった。
subDisplayForm( "", "商品一覧表" )
無知は罪。

[03/16 追記]
sDatabaseName を空に("")した場合はデータベース名の照合で最初に列挙されていた名前が利用される。
if right(oPosDB.DataSource.name, len(sDatabaseName)) = sDatabaseName then ' ←長さ=0
データベース(データソース)がひとつだけなら多分問題ないけど複数あった場合は例外発生などのエラーに
つながるだろう。だからやっぱり Function DatabaseName as string は必要。
ついでに小改造。
Sub LoadForm( FormName as string)
	subDisplayForm(ThisDatabase.Name,  FormName)
End sub

Function ThisDatabase as Object
	oForm =  ThisComponent.DrawPage.Forms.GetByIndex(0)	' DatabaseForm
	oConnection = oForm.ActiveConnection			' ConectionWrapper
	ThisDatabase = oConnection.Parent
End function

印刷マクロ / OpenOffice.org

ついでに現在のドキュメントを印刷するマクロ。
ネタ元は「StarSuite 8 Basic プログラミングガイド」か「StarSuite 8 開発者ガイド」。

REM  *****  BASIC  *****

rem ----------------------------------------------------------------------
rem define variables
public document   as object
public dispatcher as object

rem ----------------------------------------------------------------------
sub getDispatcher
	document   = ThisComponent.CurrentController.Frame
	dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
end sub

sub PrintPage
	dim args1(2) as new com.sun.star.beans.PropertyValue
	args1(0).Name = "Copies"
	args1(0).Value = 1
	args1(1).Name = "RangeText"
	args1(1).Value = "1"
	args1(2).Name = "Collate"
	args1(2).Value = false

	getDispatcher()
	dispatcher.executeDispatch(document, ".uno:Print", "", 0, args1())
end sub
フォームに貼り付けたボタンを押すと別のフォームを起動するためのマクロ。
今度も悩んだ。そしてネットを探しまわってやっと見つけた。

REM  *****  BASIC  *****

Dim oForm

sub Main
    subDisplayForm("BASEのファイル名.odb","フォーム名") 
end sub

sub subDisplayForm(sDatabaseName as string, sFormName as string)
    dim mArgs(1) as new com.sun.star.beans.PropertyValue
    oDatabase = fnGetOpenDatabase(sdatabaseName)
    oConnection = oDatabase.DataSource.getConnection("","")
    mArgs(0).name = "OpenMode"
    mArgs(0).value = "open" → オープンモードはこれらのどれかを指定するらしい
    '	"openDesign" ←
    '	"openForMail"←
    mArgs(1).name = "ActiveConnection"
    mArgs(1).value = oConnection
    oForm = oDatabase.getFormDocuments.getByName(sFormName)
    '	oForm.visibilityChanged(true)	'	何なのか不明
    oDatabase.getFormDocuments.loadComponentFromURL(sFormName, "_ blank", 0, mArgs())
end sub

function fnGetOpenDatabase(sDatabaseName as string)
    oEnum = StarDesktop.getComponents.createEnumeration
    while oEnum.hasMoreElements
        oPosDB = oEnum.nextElement
        if oPosDB.implementationName = "com.sun.star.comp.dba.ODatabaseDocument" then
            msgbox oPosDB.DataSource.name	' このメッセージボックスはデバッグ用
            if right(oPosDB.DataSource.name, len(sDatabaseName)) = sDatabaseName then
                fnGetOpenDatabase = oPosDB
                exit function
            end if
        end if
    wend
end function

ネタ元:
1) OpenOffice.org Forum at OOoForum.org :: View topic - Need Macro to Open a Form
2) Openoffice.org 2 base - un esempio mediamente avanzato

OpneOffice.org 2.0 ではマクロの削除がまともに機能していない。
削除してもそのままフォルダ内やファイル内に残り障害の原因になる。
ファイル script-lc.xml にはライブラリやモジュールのファイル名(URL)が記載されているが
削除したはずのライブラリ名モジュール名がゴミとして末尾に残ってしまう。このためマクロ読み込みに際して
「ドキュメント script-lb.xml を読み込む際のエラー / 一般的なエラー / 一般的なI/Oエラー」という
ふざけたメッセージボックスが表示される。
こうなったファイルをレスキューする方法。

今回は BASE のファイルで説明。
1) まず、ファイルの拡張子を変える。 database.odb → database.zip

2) これを解凍する。

3) 解凍されたフォルダのなかから BASIC というフォルダを見つける。

4) 不要なフォルダを削除する。ライブラリ名がついたフォルダが BASIC の下にあるのでこれを捨てる。

5) script-lc.xml というファイルを探す(すぐ見つかるはず)。
このファイルはライブラリの一覧である。これを編集して不要なテキストを削除する。
<library:libraries xmlns:library="http://openoffice.org/2000/library" xmlns:xlink="http://www.w3.org/1999/xlink">
と </library:libraries> で囲まれた範囲にあるのがライブラリ。
<library:library library:name="Standard" library:link="false"/> などというのがその中にあるはず。
この(/library:libraries>)あとにゴミがファイル末尾まで続いているのでそれを削除する。
OpenOffice.org の管理ダイアログで削除した場合は </library:libraries> が多分最後にもう一つ
くっついたままになっているのできっちり消す。
DIALOG フォルダの下のやつdialog-lc.xml も同じように編集。
[script-lc.xml の内容サンプル]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE library:libraries PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "libraries.dtd">
<library:libraries xmlns:library="http://openoffice.org/2000/library" xmlns:xlink="http://www.w3.org/1999/xlink">
<library:library library:name="Standard" library:link="false"/>
</library:libraries>
6) モジュールも管理する場合はライブラリのフォルダ(Standard等)の下にある script-lb.xml を同様に編集する。
DIALOGフォルダの中にも dialog-lb.xml というのがあるこれも必要に応じて編集する。
[script-lb.xml の内容サンプル]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE library:library PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "library.dtd">
<library:library xmlns:library="http://openoffice.org/2000/library" library:name="Standard" library:readonly="false" library:passwordprotected="false">
<library:element library:name="Module1"/>
</library:library>

7) 削除したはずの不要なモジュールがフォルダ内にいっぱいたまっていたりするので残らず処分する。

8) META-INF フォルダにある manifest.xml を編集する。不要な行を消せばいい。
消す行は以下のような行を探してみる。
「ダイアログの場合」
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="forms/Obj102/Dialogs/ライブラリ名/dialog-lb.xml"/>
<manifest:file-entry manifest:media-type="" manifest:full-path="forms/Obj102/Dialogs/ライブラリ名/"/>
「ライブラリ・モジュールの場合」
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="forms/Obj102/Basic/ライブラリ名/モジュール名.xml"/>
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="forms/Obj102/Basic/ライブラリ名/script-lb.xml"/>
<manifest:file-entry manifest:media-type="" manifest:full-path="forms/Obj102/Basic/ライブラリ名/"/>

9) さていよいよフィニッシュ。適当なアーカイバでフォルダの構造ごと一つのZipファイルにまとめる。そしてその拡張子を odb にすれば何とか復旧。
例) jar cvf ..\database.odb *

おつかれさま。

OpenOffise.org BASE でフォームに貼り付けたボタンを押したときに、
データベースのフィルタを切り替えて表示する内容を変更したかった。
3日悩んでようやくやり方が判ったのでメモしておく。

REM  *****  BASIC  *****

rem ----------------------------------------------------------------------
rem define variables
public Doc as object
public DrawPage as object
public Form as object

rem ----------------------------------------------------------------------
sub getForm
 	Doc = starDesktop.CurrentComponent	'	
	DrawPage = Doc.DrawPage		' 	
	Form = DrawPage.Forms.getByIndex(0)	'	
end sub

rem ----------------------------------------------------------------------
sub FilterBalloons
	dim qt as string	: qt = chr(34)
	dim lf as string	: lf = chr(13)

'	SELECT * FROM "商品" WHERE ("区分コード" LIKE '1*')  ORDER BY  "商品コード" ASC -- 気球関連選択
	getForm()
	Form.Filter = "(  "+qt+"区分コード"+qt+" LIKE  '1*' )"
	Form.Order = qt+"商品コード"+qt+" ASC"
	Form.ApplyFilter = true
	Form.Reload()
end sub
まず Form を取得する。
そして Form.Filter、Form.Order、Form.ApplyFilter の各プロパティをセットする。
Filter はSQL のSELECT文のWHERE 句に相当。
Order はORDER BY 句。
ApplyFilter はTrue かFalse か。(フィルタをはずしたければFalse)
さいごのReload() がミソ。

Thunderbird のあるアカウントのメッセージフィルタのルールを別のアカウントに適用したり、あるいは別のマシンにコピーしたいときは。

メッセージルールは各アカウントのフォルダ(%USERPROFILE%\Local Settings\Application Data\Thunderbird\Profiles\xxxxxxxx.default\Mail\) にある msgFilterRules.dat というファイルに保存されている。
エディタで開くと以下のようなブロックにルールが記述されているので、これをコピーして目的のアカウントに貼り付ければよい。

name="trash"
enabled="yes"
type="1"
action="Move to folder"
actionValue="mailbox://nobody@Local%20Folders/Trash"
action="Mark read"
condition="OR (from,contains,@hotmail.) OR (from,contains,@goo.) OR (from,contains,@yahoo.) OR (from,contains,@mail.goo.ne.jp)"

必要があれば適当に内容を編集すること。各行の意味はThunderbirdの「フィルタの設定」ダイアログを見たら大体想像つく。

OOo BASE へ Access のデータをインポートする方法

現在使用中のBASE のデータベースや新たに作りたいBASE にAccess やCSV のデータを取り込むには、

まず新しいDBを開きデータソースをAccess とし、目的のmdbファイルを指定してBASE から利用できるようにする。
つぎに、取り込みたいAccess 側のテーブルをBASE 側にドラッグして持ってくる。ここでデータのコピーのウィザードが起動するので、質問に従って構造だけをコピーするのか構造とデーターの両方か、どのフィールドをコピーするか、フィールドの型や長さをどうするかを指定する。
「完了」するとBASE 側に新たなテーブルが出来上がる。

他のソフトで作られたCSV ファイルを読み込むのにもほぼ同様の手順で行えばよい。CSV の場合はmdbを指定するのに該当するところが、csvファイルのあるディレクトリを指定するようになる。

インポート時にエラーが出た場合は以下を確認してみること。


1) 数値型フィールドのデータ中に不正な文字がないか。カンマもダメみたい。
2) 文字型フィールドの文字数がオーバーしてないか。
3) 入力の省略が(Null)認められていないフィールドでデータが空になっていないか。

なんでエラーになったのかメッセージを出してくれると有難いのだが。

2012年2月

      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29      

連絡先

nakanohito