「Web出版サイト」ベータ公開

Q&A集[?]

当サイトでのご質問の受付は終了しました

すべてのコンテンツを読み込み専用としたため、回答欄からも投稿できません

Apache OpenOffice/LibreOfficeのご質問はそれぞれのフォーラムへご投稿ください

質問コーナー

サイト内検索

分類メニュー

関連サイト


本日:1
昨日:1
総数:2298
現在:2


フォームのコントロールの左の矢印をクリックした時にマイマクロを実行したい。

ページOpenOffice.org FAQの登録ページ
投稿者momonnga
分類
edit/refer
優先順位
edit/refer
状態
edit/refer
カテゴリー
edit/refer
投稿日2011-04-22 10:00:23 (金)
OSwindows7home64
依存するページ
バージョン
edit/refer

メッセージ

回答ページでは行末に「~」を付加する必要はありません

フォームのテーブルコントロールの左の部分をクリックすると、緑の矢印がでて 選択状態になります。

フォームデザイン作成で、 コントロールをクリックすると、マクロを実行する方法は、なんとなく わかるのですが、緑の矢印部分がでる箇所をクリックするとマイマクロを 実行する方法はありますか?

画像にクリックする箇所を赤丸しています。 サンプルのbase用データーも添付します。


同じフォーム内にプッシュボタンを配置して、希望に近い事ができそうな事にきづきました。

momonnga (2011-04-22 16:07:16 (金))

http://oooug.jp/faq/index.php?faq/5/386
を参考にしました。
プッシュボタンには、以下のマイマクロを実行するようにしました。

Sub Me2(oEv)
 'ボタンの親のフォームを取得
 oFormA = oEv.Source.getModel().getParent()
 'フォームA の現在位置の "名前" フィールドの内容を取得
 sName = oFormA.getString(oFormA.findColumn("ID"))
 MsgBox sName
End Sub

イベントの割り当て

M.Kamataki (2011-04-23 00:23:11 (土))

マクロを実行させるためにはイベントに割り当てないといけません。当初のご質問の「緑の矢印」にはイベントの割り当てができないので無理ですね。

さて、sample2.odb を拝見しました。ボタンはプロパティでアクションに「前のレコード」や「次のレコード」を割り当てて2つ用意し、ボタンのイベントは「マウスボタンを離した時」にしています。サンプルを添付します。ファイル自身にマクロを保存しておきましたのでそのまま実行できます。どうでしょう、想定した動作になっていますか。

filefaq6_206sample3.odb

目的に近い形に作ってみました。

momonnga (2011-04-28 17:21:39 (木))

後、クリックしたボタンのLabelやnameやtagを知る事ができると、ボタンを設置しやすくなるのですが、方法はありますか?

閉じるボタンは

Sub tojiru(oEv)
 'ボタンの親のフォームを取得
 oFormA = oEv.Source.getModel().getParent()
 'フォームA の現在位置の "ID" フィールドの内容を取得
 sName = oFormA.getString(oFormA.findColumn("ID"))
 'Base ドキュメントを取得 
 oDoc = oFormA.getParent.getParent.getParent
 'ボタンの名前を習得

 bo=oFormA.getbyname("見るフォーム")
 bName=bo.name

 msgbox bName

 'フォームB の MainForm を取得
 oFormDoc = fnGetFormDoc2(oDoc,bName)

End Sub

getbyname("見るフォーム")

のプッシュボタンの名前を指定しています。

添付ファイルをアップします。

faq6_206sample4.odb
です。

ボタンのラベルを取得する

M.Kamataki (2011-04-28 22:35:22 (木))

クリックしたボタンのラベル(表示されている文字列)は次のようにすれば取得できます。

MsgBox oEV.Source.Model.Label

以下のサイトを参考にしました。

http://hermione.s41.xrea.com/pukiwiki/pukiwiki.php?OOobbs%2F36

ただし、閉じるボタンのマクロとしてご提示のものですと、クリックするボタンではなくフォームAのボタンのラベルを取得されたいようです。このような場合には対応していません。

出来ました〜。

momonnga (2011-04-29 10:29:16 (金))

ありがとうございます。

連休は、CSVの書き出しと、フォームの更新を追加してみる予定です。

faq6_206sample5.odb
に訂正したのを添付します。

ボタンのイベント

M.Kamataki (2011-05-02 21:46:27 (月))

マクロはプッシュボタンの「実行時」に割りつけるのが良いと思います。

配列変数の数が未定の場合の方法はありますか?

momonnga (2011-05-13 08:58:07 (金))

なんとなくCSV書き出しだできそうになってきました。
列の数がフォームの作り方で変わってくるのですが、

DIM items() as string

にするとエラーがでました。

これは違っているのでしょうか?

現在、

DIM items(takazu) As string

で、数を割り当てしています。

sub tbda2(oEv)
 DIM i As long
 DIM takazu As long
 DIM items() As string
 oFormA = oEv.Source.getModel().getParent()
 oFormA.beforeFirst
'テーブルの列の数を得る
 takazu=oFormA.getMetaData().getColumnCount()
items(1)=oFormA.getMetaData().getColumnName(1)
msgbox  items(1)
  oFormA.next
 msgbox join(items,",")
end sub

数を割り当てしている部分

sub tbda(oEv)
 DIM i As long
 DIM takazu As long
 oFormA = oEv.Source.getModel().getParent()
 oFormA.beforeFirst
'テーブルの列の数を得る
 takazu=oFormA.getMetaData().getColumnCount()
  DIM items(takazu) As string
items(1)=oFormA.getMetaData().getColumnName(1)
msgbox  items(1)
  oFormA.next
 msgbox join(items,",")
end sub

添付ファイルはfaq6_206sample6.odbでアップします。

calcへ書き出しまでできました。

momonnga (2011-05-13 17:13:44 (金))

faq6_206sample7.odbでcsvまで書き出しができるようになりました。
配列の数は割り当てで行っています。

最終的に〜.csvにするなら

M.Kamataki (2011-05-13 23:57:57 (金))

現在はCalcファイルへの書き出しですね。最終的にCSVファイルにするなら、以下のサイトが参考になります。

OOoBasic/Calc/CSV
http://hermione.s41.xrea.com/pukiwiki/pukiwiki.php?OOoBasic%2FCalc%2FCSV

今のままですと、数値フィールドもテキスト扱いになっています。最後にCSV フィルターオプションで書き出すのが楽ですね。ただし、汎用的なマクロにするためには、データ型の取得が面倒そうです。以下のサイトのgetメソッドが使えそうですが、やはり面倒そう。

データベースアクセス
http://wiki.services.openoffice.org/wiki/JA/Documentation/BASIC_Guide/Database_Access

calcへ値を送るのを4つに分けるのを作りました。

momonnga (2011-05-16 11:53:35 (月))

もうすぐスパッゲッティ状態になりそうです。
stringからvalueへ代入していますが、大丈夫でしょうか?

sub tbda(oEv)
 DIM i As long
 DIM takazu As long
 DIM csvda As string
Dim oDoc As Object
'calcを開く
 oDoc = StarDesktop.loadComponentFromURL( "private:factory/scalc","_blank",0,Array() )
 oFormA = oEv.Source.getModel().getParent()
'列の数を得る
 takazu=oFormA.getMetaData().getColumnCount()
 
'列のタイプを入れる配列
  DIM itemtypes(takazu-1) As string
'列のタイプを数値は0 テキストは1 数式は2を入れる配列
  DIM calcin(takazu-1) As long
  
'1行目の処理
 For i=0 to takazu-1

'列のタイプを取得
itemtypes(i)=oFormA.getMetaData().getColumntypename(i+1)
'列の項目をセット
StarDesktop.CurrentComponent.sheets(0).getcellbyposition(i,0).string=oFormA.getMetaData().getColumnName(i+1)
'列のタイプを数値は0 テキストは1 数式は2 日付関係は3を入れる 真ん中の値のうけわたしが数式にする列の行なければ未設定
calcin(i)=ftype(itemtypes(i),,i)
next
 oFormA.beforeFirst
 DIM t As long
 t=0
 While oFormA.next()
 t=t+1
 For i=0 to takazu-1
'列のタイプによって4つに振り分け
 if (calcin(i)=1)then
  StarDesktop.CurrentComponent.sheets(0).getcellbyposition(i,t).string=oFormA.getString(i+1)
 elseif (calcin(i)=0) then
  StarDesktop.CurrentComponent.sheets(0).getcellbyposition(i,t).value=oFormA.getstring(i+1)
 elseif(calcin(i)=3)then
  StarDesktop.CurrentComponent.sheets(0).getcellbyposition(i,t).value=oFormA.getlong(i+1)
 else
   StarDesktop.CurrentComponent.sheets(0).getcellbyposition(i,t).Formula=oFormA.getstring(i+1)
 end if
 next

WEnd

end sub

'日付とテキストと数値と数式の列指定で条件をわける関数
function ftype( ty as string,typeother as long,iarg as long) as long
if (typeother -1 = iarg)then
ftype=2
elseif (ty="INTEGER") or (ty="TINYINT") or (ty="BUGINT") or (ty="NUMERIC") or (ty="DECIMAL") or (ty="SMALLINT") or(ty="FLOAT") or(ty="REAL") or (ty="DOUBLE") then
ftype=0
elseif (ty="DATE") or (ty="TIME") or(ty="TIMESTAMP")then
ftype=3
else
ftype=1
end if
end function

添付ファイルはfaq6_206sample8.odbに添付します。

case文使って一個一個しても大丈夫かな?

momonnga (2011-05-16 13:08:14 (月))

pentium4のパソコン使っているのですが、何か付属のマクロとかないでしょうか?

フォームの内容のCSV出力

ike@九州 (2011-05-16 13:36:38 (月))

faq/5/348 にて例を作成しています。
doImport メソッドを使うと Calc へデータタイプ自動判別して書き出されます(書式も自動設定されてしまいますが…)

但し、該当フォームのある Baseドキュメントのデータベース登録が必須です
(これもマクロで登録、解除はできますが)

データーベースネームを得る

momonnga (2011-05-16 16:05:11 (月))

少しまだ理解するのに時間がかかりそうなのですが、データーベースの登録
は、登録名を得るとそのまま使えますか?

oConnection = oFormA.ActiveConnection
ThisDatabase = oConnection.Parent
msgbox ThisDatabase.name

クリックしたフォームから、データーベース名をたどっています。

イベントサンプルです

ike@九州 (2011-05-16 17:53:38 (月))

適当に応用してください

sub tbda2(oEv)
 oFormA = oEv.Source.getModel().getParent() 
 oConnection = oFormA.ActiveConnection
 MsgBox getRegisterdDBName(oConnection.Parent)
end sub

'データベース登録名の取得
Function getRegisterdDBName(oDataSource As Object) As String

 If Instr(oDataSource.Name,"file") = 0 Then
  registerName = oDataSource.Name
 Else
  s = dir(oDataSource.name)
 registerName = Left(s,Len(s) - 4)
 End If
'全ての登録名の取得 
oDatabaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") 
oDBSource = oDatabaseContext.getRegistrationNames

For n = 0 To ubound(oDBSource)

 On Error Resume Next
 oDataBase =  oDatabaseContext.getByName(oDBsource(n))
 IF oDBSource(n) = registerName Then
  '登録名が一致したらデーソースURLを新しく上書き
  oDatabaseContext.changeDatabaseLocation(registerName,oDataSource.DatabaseDocument.URL)
  getRegisterdDBName = registerName
  Exit Function
 Else
  'データソースURLが一致したらその登録名の取得   
  If oDataBase.name = oDataSource.DatabaseDocument.URL Then
   getRegisterdDBName = oDBsource(n)
   Exit Function
  End If    
 End IF

Next
On Error Goto 0
'登録されていない場合は新規データベース登録
oDatabaseContext.registerObject(registerName,oDataSource)
getRegisterdDBName = registerName

End Function

ありがとうございます!

momonnga (2011-05-17 09:06:23 (火))

Bibliographyを発見しました。これって、もしかして使えるのでしょうか?

とりあえず、設置してみました。

momonnga (2011-05-17 13:41:46 (火))

うごきました〜。
まだよくわからない部分があるのですが、いろいろと調べてみたいと思います。
Connection.createStatement()
あたりが、なんとなく気になっています!

添付ファイルはfaq6_206sample9.odbに添付します。

sub doin(oEv)
Dim oCalcDoc As Object
Dim args(0) As New com.sun.star.beans.PropertyValue
Dim args1(2) As New com.sun.star.beans.PropertyValue
Dim args2(1) As New com.sun.star.beans.PropertyValue
'calcを開く
oCalcDoc = StarDesktop.loadComponentFromURL( "private:factory/scalc","_blank",0,Array() )
'データーベースの登録~
oFormA = oEv.Source.getModel().getParent() 
oConnection = oFormA.ActiveConnection
sDBName = getRegisterdDBName(oConnection.Parent)
'Calcにフォームのソース元のクエリを書き出し(上限65536行)
oFormA = oEv.Source.getModel().getParent()
TargetSheet = oCalcDoc.getSheets().getByIndex(0)   
oImportRange = TargetSheet.getCellRangeByName("A1")
args1(0).Name = "DatabaseName"
args1(0).Value = sDBName
args1(1).Name = "SourceType"
Select case oFormA.CommandType
 case 0
 args1(1).Value = com.sun.star.sheet.DataImportMode.TABLE
 case 1
 args1(1).Value = com.sun.star.sheet.DataImportMode.QUERY
 case 2
 args1(1).Value = com.sun.star.sheet.DataImportMode.SQL
End Select
args1(2).Name = "SourceObject
args1(2).Value = oFormA.Command
oImportRange.doImport(args1)
end sub

データーベースの場所が変わると

momonnga (2011-05-17 14:09:12 (火))

faq6_206sample9.odbのは、データーベースの場所が変わるとエラーになります。

エラー処理

ike@九州 (2011-05-17 16:25:04 (火))

データベースの移動でエラーが出ないように
データソースURLを常に上書きするようにコード修正しました。

フィルター適用後の部分だけ書き出しって方法ありますか?

momonnga (2011-05-25 09:38:46 (水))

本データーベースに設置したら、テーブルが全部でてきました〜。

フィルター適用後の部分だけ欲しいときは?何か方法がありますか?

宅配伝票出力ソフトにデーターを1個〜200個ぐらい発生する時がよくあります。

フォームのフィルタリング?

M.Kamataki (2011-05-25 11:34:50 (水))

お書きになった意味を理解できているのか不安ですが、起動時のフォームのフィルタリングならできます。

たとえば添付されたサンプルですと、MainFormの「フォームの属性」ダイアログボックスの「データ」タブのフィルタ欄を設定すれば、フォーム起動時のデータ量を少なくすることは可能です。

起動時のフォームをフィルタリングした後

momonnga (2011-05-25 13:18:12 (水))

calcへの転送をフィルタリングした分だけを行うのが希望です。

フォームの属性設定はやってみましたが、フォームの設定のテーブルが全部calcへ転送なるのが現在の状況です。

oFormA = oEv.Source.getModel().getParent()
oFormA.next()

でレコードが移動できるFormは、不思議な気持ちがしています!

サンプル

ike@九州 (2011-05-25 13:46:52 (水))

全て SQL として書き出す内容にしてみましたが
本番では上手くいくでしょうか?
WHERE句が2個以上あると終了するようにしています

'Calcにフォーム内容をSQLとして書き出し
oFormA = oEv.Source.getModel().getParent()
TargetSheet = oCalcDoc.getSheets().getByIndex(0)   
oImportRange = TargetSheet.getCellRangeByName("A1")
args1(0).Name = "DatabaseName"
args1(0).Value = sDBName
args1(1).Name = "SourceType"
args1(1).Value = com.sun.star.sheet.DataImportMode.SQL
args1(2).Name = "SourceObject"
sSQL = oFormA.ActiveCommand 
IF oFormA.ApplyFilter = true and oFormA.Filter <>"" Then
  sWhere = "WHERE"
  'split では大文字、小文字を区別するので Instr で実文字取得
  IF Instr(sSQL," where ") > 0 Then sWhere = mid(sSQL,Instr(sSQL," where ")+1,5)
  sFilter = split(sSQL,sWhere)
  Select Case uBound(sFilter)
    Case 0
     sSQL = sFilter(0) & " WHERE " & oFormA.Filter
    Case 1
     sSQL = sFilter(0) & "WHERE " & oFormA.Filter & " AND" & sFilter(1)
    Case Else
     msgbox "SQLが複雑すぎます"
     Exit Sub
  End Select
End IF
args1(2).Value = sSQL
oImportRange.doImport(args1)


#ANDを付加して修正しました m(_ _)m

うごきました〜。

momonnga (2011-05-25 14:49:11 (水))

SQLシンタックスエラーがでたので、

sSQL = sFilter(0) & "WHERE " & oFormA.Filter & sFilter(1)

を、andをつけてみました。

sSQL = sFilter(0) & "WHERE " & oFormA.Filter & "and" & sFilter(1)

いろいろちょっと試してみます。

mac os Xからwindows共有 パスワード設定ありでやってみました。

momonnga (2011-05-26 11:05:53 (木))

動きました〜。ありがとうございます!

フィルターがorで2個の時止まるので

momonnga (2011-06-07 09:00:46 (火))

sSQL = sFilter(0) & "WHERE " & oFormA.Filter & " AND" & sFilter(1)

これですが、orのフィルターで実行すると、baseが動かなくなってしまうので、以下になおしたら、大丈夫でした。

sSQL = sFilter(0) & "WHERE " & " ("& oFormA.Filter & ") and" & sFilter(1)

カッコでくくってみました〜。

止まった時のSQLを参考に。(項目などは加工しました)

momonnga (2011-06-07 09:23:57 (火))

SELECT "顧客"."顧客ID" AS "顧客ID", "顧客"."電話番号" AS "電話番号", "顧客"."苗字" AS "苗字", "顧客"."名" AS "名", "顧客"."郵便番号1", "顧客"."郵便番号2", "顧客"."県名" AS "県名", "顧客"."住所1" AS "住所1", "顧客"."住所2" AS "住所2", "顧客"."住所3", "顧客"."会社名" AS "会社名", "顧客分類明細"."会員NO" AS "会員NO", "顧客分類"."顧客分類名" AS "顧客分類名", MAX( "入金"."初回号数" ) AS "初回", MAX( "入金"."最終号数" ) AS "最終号数", CONCAT( CONCAT( CONCAT( CONCAT( '(', "初回号数" ), '-' ), "最終号数" ), ')' ) AS "ラベル用" FROM "顧客分類明細", "顧客", "顧客分類", "入金" WHERE ( "電話番号" = '000-000-0000' ) OR ( "会員NO" = 0000000 ) and "顧客分類明細"."顧客ID" = "顧客"."顧客ID" AND "顧客分類明細"."顧客分類ID" = "顧客分類"."顧客分類ID" AND "入金"."顧客ID" = "顧客"."顧客ID" GROUP BY "顧客"."顧客ID", "顧客"."電話番号", "顧客"."苗字", "顧客"."名", "顧客"."郵便番号1", "顧客"."郵便番号2", "顧客"."県名", "顧客"."住所1", "顧客"."住所2", "顧客"."住所3", "顧客"."会社名", "顧客分類明細"."会員NO", "顧客分類"."顧客分類名" HAVING ( ( "顧客分類"."顧客分類名" = 'B会員' ) OR ( "顧客分類"."顧客分類名" = 'A会員' ) ) ORDER BY "会員NO" ASC, "最終号数" ASC

お名前:
題名:


添付ファイル: filefaq6_206sample10.odb 902件 [詳細] filefaq6_206sample9.odb 427件 [詳細] filefaq6_206sample8.odb 419件 [詳細] filefaq6_206sample7.odb 421件 [詳細] filefaq6_206sample6.odb 434件 [詳細] filefaq6_206sample5.odb 440件 [詳細] filefaq6_206sample4.odb 444件 [詳細] filefaq6_206sample3.odb 970件 [詳細] filesample2.bas 299件 [詳細] filesample2.odb 448件 [詳細] filetoi.gif 444件 [詳細] filesample.odb 420件 [詳細]