2008年12月アーカイブ

ErrorOfInsertNewRec.jpg

Excel や Calc の表からデータベースにデータを移行するマクロを書いていて
表題のようなエラーに出くわした。
原因は分らない。
回避策として OnError 文でリトライを掛けることにした。
一見うまく行ったように見えたのだが、よく調べるとデータの欠落を起こしている
場合もある。仕方ないのでこのエラーがでたときは再度同じファイルを読み込ま
せる様に運用することにした。
トランザクションにしてロールバックすればよりよい対処ができるのだろうが。
めんどい。

[変更前]
function insertDetailTable(recset as object, sheet as object, file_id as integer, bill_id as integer , row as integer)
	C = recset.Columns
	row_index = row +1
	rem_cell	= sheet.getCellByPosition(1,row)	' B:摘要
	qty_cell	= sheet.getCellByPosition(6,row)	' G:数量
	price_cell	= sheet.getCellByPosition(7,row)	' H:単価
	amount_cell	= sheet.getCellByPosition(8,row)	' I:金額
	
	item_name	= convertCharCode(rem_cell.string)
	quantity	= qty_cell.value
	unit_price	= price_cell.value
	amount		= amount_cell.value

	recset.moveToInsertRow()
	recset.updateInt(C.findColumn("BILL_ID"), bill_id)
	recset.updateInt(C.findColumn("FILE_ID"), file_id)
	recset.updateInt(C.findColumn("ROW"), row_index)
	recset.updateString(C.findColumn("ITEM_NAME"), item_name)
	recset.updateDouble(C.findColumn("UNIT_PRICE"), unit_price)
	recset.updateDouble(C.findColumn("QUANTITY"), quantity)
	recset.updateDouble(C.findColumn("AMOUNT"), amount)
	recset.insertRow()	' ここでエラーが出てくる
	insertDetailTable = recset.getInt(C.findColumn("ID"))
end function


[変更後]
function insertDetailTable(recset as object, sheet as object, file_id as integer, bill_id as integer , row as integer)
	errcnt = 0

ErrorRetry:
	C = recset.Columns
	row_index = row +1
	rem_cell	= sheet.getCellByPosition(1,row)	' B:摘要
	qty_cell	= sheet.getCellByPosition(6,row)	' G:数量
	price_cell	= sheet.getCellByPosition(7,row)	' H:単価
	amount_cell	= sheet.getCellByPosition(8,row)	' I:金額
	
	item_name	= convertCharCode(rem_cell.string)
	quantity	= qty_cell.value
	unit_price	= price_cell.value
	amount		= amount_cell.value

	recset.moveToInsertRow()
	recset.updateInt(C.findColumn("BILL_ID"), bill_id)
	recset.updateInt(C.findColumn("FILE_ID"), file_id)
	recset.updateInt(C.findColumn("ROW"), row_index)
	recset.updateString(C.findColumn("ITEM_NAME"), item_name)
	recset.updateDouble(C.findColumn("UNIT_PRICE"), unit_price)
	recset.updateDouble(C.findColumn("QUANTITY"), quantity)
	recset.updateDouble(C.findColumn("AMOUNT"), amount)

	on error goto ErrorHandler
	recset.insertRow()
	insertDetailTable = recset.getInt(C.findColumn("ID"))
exit function

ErrorHandler:
	on error goto 0
	if (errcnt < 5) then
		errcnt = errcnt+1
		resume ErrorRetry
	else
		msgBox err &":"& error(err) &chr(13) _
			& "TAB:"& sheet.Name &chr(13) _
			& "ROW:"& row_index &chr(13) _
			& item_name &" / "& quantity &"*"& unit_price &chr(13) _
			& "この行はデータベースに追加できませんでした。"

		insertDetailTable = -2
		exit function
	endif
end function

OOo BASE フィルターの バグ

テーブルやクエリーを直接開いて標準クエリーで
得意先 同じ(LIKE のことらしい) '(株)*' とすると"(株)日本電気" などの "(株)"で始まる名前がセレクトされるはずなんですが、"(有)とかち商店" などもでてきてしまう。

'(株)*' をOpenOffice.org が勝手に '(*)*' に変換してくれている。
'(有)*' とすれば変換は起こらない(正しい)ので (有) ではじまる名前だけをセレクトできる。
SQL で一般的なワイルドカードの '%' を '*' に変換したりしているからこの絡みだろう。
たぶんマルチバイト系の文字の処理を手抜きしてシングルバイト系の処理に渡していろう。

OOo 3.0 で気がついたが、2.4 でも同様に確認できた。

com.sun.star.util.DateTime

日付、時刻やタイムスタンプに使われる構造体

var = CreateUnoStruct("com.sun.star.util.DateTime")
で用意する。
com.sun.star.util.DateTime
メンバ名
HundredthSeconds asinteger
Secondsinteger
Minutesinteger
Hoursinteger
Dayinteger
Monthinteger
Yearinteger

Excel のファイルを Calc に読み込むと何故かページが分割される。
ページの余白や各行の高さなどが一致していてもExcelだと1ページに印刷されるものが
Calc だと 2ページになって印刷されてしまう。

ずっと以前からそういうものなのだと思っていたのだが、何故なのか調べたことはなかった。
先日、職場で使われている請求書の原稿を調べていたとき原因を発見。

Excel って印刷時に行の高さをパーセンテージで調整できるのですね。
まったく知りませんでした。1ページに印刷されていたのはこの機能を使って
全体を押しつぶした感じで印刷していたのか。

さらに調べると横方向は特に押し縮めてはいないようだし。
フォントのサイズも変わらないみたい。

なら、行の高さを一括して任意%に 変更するマクロで移行で切るじゃん?
で、作ってみました。

「何%に」というプロンプトは変更する行高さのパーセンテージ。
デフォルトは90% 。 100%以上もOKです。

「何行目〜」というのは全シートの n 行目から m 行目に対して変更を加えるという指定。
デフォルトは 1〜40

「何頁目〜」というのは何枚目のシートからという指定での印刷ページのことではない。
デフォルトは1〜最後のシートまで。

sub RowHeight
	Dim Doc As Object
	Dim Sheet As Object
	Dim Row As Object
	Doc = StarDesktop.CurrentComponent
	Mag = cdbl(inputBox("何%に","行の高さ変更",90))
	Top = cint(inputBox("何行目から", "行指定",1))-1
	Bottom = cint(inputBox("何行目まで", "行指定",40))-1
	First = cint(inputBox("何頁目から", "頁指定",1))-1
	Last = cint(inputBox("何頁目まで", "頁指定",Doc.Sheets.Count))-1
	for s=First to Last
		Sheet = Doc.Sheets(s)
		for i=Top to Bottom
			Row = Sheet.Rows(i)
			Row.Height = Row.height * Mag/100
		next
	next
end sub

連絡先

nakanohito