Top > OOobbs > 62

OOobbs/62 Edit

  • サマリ: ListBoxにオープンしている他のドキュメントからセルの値
  • 環境: Calc
  • 状態: 解決
  • 投稿者: 茶菓?
  • 投稿日: 2005-04-26 (火) 13:55:00

質問 Edit

calcでダイアログのListBoxにオープンしている、ほかのドキュメントのシートのセルの値を入力(表示)させるマクロを どなたか教えてもらえませんか? エクセルで作った表をOOoに移植しているのですが、マクロのほとんどが動かなくて困っています。  宜しく、お願いします。

回答をいただいたのですが、私の説明不足ですので再度質問します。  具体的には、見積書を作成する見積表(ドキュメント)と、見積書に品名と単価を記入するための単価表(ドキュメント)を読み込んで見積書のシートに単価表のシートから品名と単価を記入したいのです。

 単価表のシートは、以下の以下の様になっているものとします。

   分類1    分類2         分類x
 
 品名 単価 品名 単価       品名 単価
 
 aaa   100 a12  1500       x12  1100
 bbb   110 b13  2000       y23  1230
 xxx   200 x45  5500       z90   900

 見積書のシートの、ダイアラグのLisBox1には、単価表のシートの分類1から分類xのセルの文字を表示させたいのです。

 次に、ListBox1で選択した分類に応じて、たとえば分類2を選択したら分類2 の品名をここでは、a12,b13,,,x45 をListBox2に表示させたいのです。  そして、ListBox2である品名を選択したら、見積書のシートの品名の項目に 選択した品名を、単価の項目に選択した品名の単価を記入したいのです。

 とりあえず、見積書のシート上のダイアラグのListBox1に単価表のシートから分類のセルの文字を表示させたいマクロを、教えて貰いたいです。  宜しく、お願いします。

ページの更新をしたら、 テキスト整形のルールにもとずいていないみたいで、上の単価表のシートの文字がずれて表示されていますが、大体の推測でお願いします。  本当は、もう少し練習してから質問するべきでしょうが、申し訳ありません。

 どなたか修正してくれたみたいで、有難うございます。

回答 Edit

  • 移植は大変ですね。詳しい仕様や使い方が質問内容からよく汲み取れなかったので,とりあえず,プロトタイプを作成しました。

ファイル: fileOOobbs62-1.sxc

マクロの部分は次のようになっています。

Dim oDialog As Object, oMDialog As Object
Dim oDoc As Object, oController As Object
Sub Main
Dim oSheets As Object, oSheet As Object
  oDoc = ThisComponent
  oController = oDoc.getCurrentController()
  oSheet = oController.getActiveSheet()
  DialogLibraries.LoadLibrary("Standard")
  oDialog = CreateUnoDialog(DialogLibraries.Standard.Dialog1)
  oMDialog = oDialog.getModel()
  oDialog.execute()
  oDialog.dispose()
End Sub
Sub Insert
Dim oLocDoc As Object
Dim sUrl As String
Dim sCell As String
Dim oCell As Object
Dim oOuterCell As Object
  sUrl = oDialog.getControl("ListBox1").getSelectedItem()
  If NOT (sUrl = "") Then
    oCell = oController.getSelection().getCellByPosition(0,0)
    oLocDoc = OpenDocument(ConvertToUrl(sUrl))
    oOuterCell = oLocDoc.getSheets().getByIndex(0).getCellRangeByName("A1")
    oCell.String = oOuterCell.String
    oLocDoc.close(true)
  End If
End Sub
Function OpenDocument(sLocUrl As String) As Object
Dim aArg(0) As New com.sun.star.beans.PropertyValue
  aArg(0).Name = "Hidden"
  aArg(0).Value = true
  OpenDocument = StarDesktop.loadComponentFromUrl(sLocUrl, "_blank", 0, aArg())
End Function

とりあえず,リストボックスに与えたファイル名 "C:\usr\temp\data-1.sxc" のセル "A1" の文字列を取得,現在のドキュメントの選択セル範囲の左上のセルに文字列を挿入するように作成しました。

リストボックスにはあらかじめアドレスを入れておきましたが,現在開かれているドキュメントのアドレスを取得して入れてやることもできます。

  • Main: マクロの本体。ダイアログの表示を行う。
  • Insert: "Insert" ボタンに割り当てるプロシージャ。
  • OpenDocument: 与えたドキュメントの Url からドキュメントオブジェクトを戻す。このとき,ドキュメントの "Hidden" 属性を true にしてドキュメントのウィンドウが開かないようにすることができる。

もう少し具体的なことが分かれば作り直したいと思いますが ...

  • はにゃ?? 2005-04-28 (木) 01:14:44

その 2 Edit

  • 回答有難うございます。私の説明が不足のため質問に追加しましたので、もしよろしければまたよろしくお願いします。--茶菓? 2005-04-28 (木) 15:30:00
  • 単価表ドキュメントのフォーマットに柔軟に対応するような形式にすべきかどうか迷ったのですが,中途半端に柔軟になってしまいました。こちらで勝手に想定して作成した単価表に基づいたものを作成してみました。

質問中で,「ダイアログ」と書かれていましたがドキュメント中に貼り付ける形のフォームの間違いでしょうか?

続きは後ほど ...

  • はにゃ?? 2005-04-30 (土) 10:11:18
  • よろしくお願いします。ところで、ダイアログとフォームの違いがわかりません。エクセルからcalcに移植したら、エクセルのフォームがcalcのマクロのbasicエディタでは、ダイアログになっていましたのでダイアログでいいものと思っていました。
  • 茶菓? &new([nodate]){date}: Invalid date string;
  • とりあえず,分類の部分をリストボックスに挿入する部分を作成しました。

OpenOffice.org ではドキュメント上に配置したボタンやリストボックスなどがフォームと呼ばれます。ダイアログエディタで作成されるようなものがダイアログと呼ばれています。

file見積書.sxc

file単価表.sxc

単価表のフォーマットは上記のものとして作成しました。

  oItemDoc = OpenDocument(ConvertToUrl("C:\単価表.sxc"))

の行に単価表ファイルのパスを書き込んでください。

Dim oDoc As Object, oController As Object
Dim oActiveSheet As Object
Dim oDrawPage As Object
Dim oForm As Object
Dim oListBox1 As Object
Dim oItemDoc As Object
Dim oClassRange As Object


Sub Main
  oDoc = ThisComponent
  oController = oDoc.getCurrentController()
  oActiveSheet = oController.getActiveSheet()
  oDrawPage = oActiveSheet.getDrawPage()
  oForm = oDrawPage.getForms().getByName("Standard")

  oListBox1 = oForm.getByName("ListBox1")
  oItemDoc = OpenDocument(ConvertToUrl("C:\単価表.sxc"))
  PutClasses(oItemDoc.getSheets().getByName("Sheet1"))
  'oListBox1.StringItemList = PutClasses(oItemDoc.getSheets().getByName("Sheet1"))
  oItemDoc.close(true)
End Sub


Sub PutClasses(oLocSheet As Object)
Dim oCursor As Object
Dim oClassRange As Object
Dim aStart As New com.sun.star.table.CellRangeAddress
Dim aEnd As New com.sun.star.table.CellRangeAddress
  oCursor = oLocSheet.createCursor()
  oCursor.gotoStartOfUsedArea(false)
  aStart = oCursor.RangeAddress
  oCursor.gotoEndOfUsedArea(false)
  aEnd = oCursor.RangeAddress
  oClassRange = oLocSheet.getCellRangeByPosition(0, 0, aEnd.EndColumn, aEnd.EndRow)
  
Dim sClasses(Int((aEnd.EndColumn)/2)) As String
Dim oLocCell As Object
Dim i As Integer, j As Integer
  j = 0
  For i = 0 To aEnd.EndColumn
    oLocCell = oClassRange.getCellByPosition(i, 1)'row 2
    If Not (oLocCell.String = "") Then
      sClasses(j) = oLocCell.String
      j = j + 1
    End If
    i = i + 1
  Next i
  'oListBox1.StringItemList = Array()
  oListBox1.StringItemList = sClasses()
  'GetClasses = sClasses()
End Sub


Function OpenDocument(sLocUrl As String) As Object
Dim aArg(0) As New com.sun.star.beans.PropertyValue
  aArg(0).Name = "Hidden"
  aArg(0).Value = false
  OpenDocument = StarDesktop.loadComponentFromUrl(sLocUrl, "_blank", 0, aArg())
End Function

Main を実行するとドキュメント上に作成したフォームの ListBox1 に分類項目が設定されます。

分類項目の数が変化してもある程度対応できるように作成してみました。

単価表のファイルを読み込む際にどのくらい柔軟性が必要でしょうか?

  • はにゃ?? 2005-04-30 (土) 19:30:35
  • 少しずつ解説します。まず,Main プロシージャの部分です。
Sub Main
 oDoc = ThisComponent
 oController = oDoc.getCurrentController()
 oActiveSheet = oController.getActiveSheet()
 oDrawPage = oActiveSheet.getDrawPage()
 oForm = oDrawPage.getForms().getByName("Standard")

 oListBox1 = oForm.getByName("ListBox1")
 oItemDoc = OpenDocument(ConvertToUrl("C:\単価表.sxc"))
 PutClasses(oItemDoc.getSheets().getByName("Sheet1"))
 'oListBox1.StringItemList = PutClasses(oItemDoc.getSheets().getByName("Sheet1"))
 oItemDoc.close(true)
End Sub

Calc ドキュメントのフォームはシートごとに存在するドローページに所属しています。前半の部分でフォームにアクセスできるようにしています。そして,リストボックス名 "ListBox1" オブジェクトを取得します。

次に,OpenDocument プロシージャを呼び出してドキュメントを開いています。そして,PutClasses プロシージャによってリストボックスにリストを設定しています。

最後は単価表のドキュメントを閉じています。今のところ単価表のドキュメントをウィンドウが見えるように開いていますが,非表示として開くこともできます。

Sub PutClasses(oLocSheet As Object)
Dim oCursor As Object
Dim oClassRange As Object
Dim aStart As New com.sun.star.table.CellRangeAddress
Dim aEnd As New com.sun.star.table.CellRangeAddress
  oCursor = oLocSheet.createCursor()
  oCursor.gotoStartOfUsedArea(false)
  aStart = oCursor.RangeAddress
  oCursor.gotoEndOfUsedArea(false)
  aEnd = oCursor.RangeAddress
  oClassRange = oLocSheet.getCellRangeByPosition(0, 0, aEnd.EndColumn, aEnd.EndRow)
  
Dim sClasses(Int((aEnd.EndColumn)/2)) As String
Dim oLocCell As Object
Dim i As Integer, j As Integer
  j = 0
  For i = 0 To aEnd.EndColumn
    oLocCell = oClassRange.getCellByPosition(i, 1)'row 2
    If Not (oLocCell.String = "") Then
      sClasses(j) = oLocCell.String
      j = j + 1
    End If
    i = i + 1
  Next i
  oListBox1.StringItemList = sClasses()
End Sub

柔軟性を与えるために,使用されているセル範囲を判断して取得しています。分類項目が 2 行目にあるとして項目を取得します。項目が一列ごとにあるとしています。

リストボックス ListBox1 に項目を設定するには StringItemList プロパティーを使用して行います。

OpenDocument の部分に関してはOOoBasic/Generic/documentのページを参考にしてください。

  • はにゃ?? 2005-04-30 (土) 20:01:25
  • 添付ファイルをダウンロードすると、zipファイルのフォルダーができてしまいます。calcでよめる*.sxcファイルにするには、どうしたらよいのでしょうか? ヘルプのxml形式うんぬんのところを、調べていますがよくわかりません。 初心者で、申し訳ございません。
  • 茶菓? &new([nodate]){date}: Invalid date string;
  • ファイル名が日本語だったのがいけなかったのでしょうか?zip ファイルとして保存されてしまうのであれば,ファイル名を *.sxc あとで変更してやるか,または,そのまま Calc のメニューからファイルを開くとファイルが読み込めると思います。ファイル名をアルファベットに変更したファイルも置いておきました。
  • はにゃ?? 2005-05-01 (日) 02:21:32

その 3 Edit

  • なんとか添付ファイルをcalcで読み込んで実行することが出来ました。アルファベットのファイルでもzipファイルになります。見積書のマクロのmainをドキュメントを開くに割り当てることでうまくいきます。 エクセルでは、見積書のドキュメントのマクロから単価表のドキュメントを見積書のドキュメントを開くときに、単価表のドキュメントを開いています。そして、見積書のドキュメントをフロントにしています。それは、この掲示板の質問9を参考にしてうまくいきました。 ご提示いただいた、サンプルでは単価表を開くときにListBox1にリスト項目を読み込む(書き込む?)のですが、できれば開いている単価表のセルのアドレスから、サンプルではA2、C2、E2のセルのデータをListBox1に読込むマクロが欲しいです。そうでないと、ListBox1の分類項目を選択してListBox2の品名項目を読込むマクロが大変になると思います。現状エクセルでは、両方開いていて見積書ドキュメントを閉じるときに、マクロで先に単価表ドキュメントを閉じるようにしています。 また、現状の見積書シートには”品名記入ボタン”を押したらListBox1,2の入ったダイアログがシート上に開くようにしています。この辺までは、calcのマクロでもなんとか動くようにしました。注文ばかりで失礼ですが、宜しくお願いします。
  • 茶菓? &new([nodate]){date}: Invalid date string;
  • zip になるのはブラウザの設定のせいですね。

単価表のセルのアドレスから読み込む方法でよかったのですね。単価表の分類項目数が増えたときなどに対処しようと考えて作成してしまいました。ごめんなさい。

「また、現状の見積書シートには”品名記入ボタン”を押したらListBox1,2の入ったダイアログがシート上に開くようにしています。」ということは,フォームではなくてやはりダイアログだったのですね。"シート上" と書かれていたのでフォームと勘違いしてしまいました。

フォームからダイアログに変更することにします。

  • はにゃ?? 2005-05-01 (日) 15:09:07
  • ブラウザの設定のせいとは、使用しているのはインターネットエクスプローラ6です。 どこを設定し直せばよいのでしょうか?なお、この掲示板の質問9を参考は質問5の間違いでした。
  • 茶菓? &new([nodate]){date}: Invalid date string;
  • インターネットエクスプローラをあまり使っていないので,設定に関して分からないのですが,添付ファイルをダウンロードする際には,マウスで右クリックして「対照をファイルに保存」を選択してもらって,保存ダイアログの「ファイルの種類」を「すべてのファイル」とするといいと思います。 -- はにゃ?? 2005-05-02 (月) 00:25:27
  • 続きです。

単価表は同じものを使用して,見積書を変更しました。

Main プロシージャの unit_value_file = の行に見積書ファイルのパスを指定してください。

fileestimate-2.sxc

Dim oDoc As Object
Dim oDialog As Object
Dim oListBox1 As Object
Dim oListBox2 As Object
Dim oItemDoc As Object
Dim unit_value_file As String
Sub Main
  on error goto Error
  Dim oFrames As Object
  Dim j As Integer
  unit_value_file = _
     "C:\Documents and Settings\My Documents\test\unit_value.sxc"
  oFrames = StarDesktop.getFrames()
  For j = 0 To oFrames.getCount() -1
    If oFrames.getByIndex(j).getController().getModel().getURL() = _
        ConvertToUrl(unit_value_file) Then
      oItemDoc = oFrames.getByIndex(j).getController().getModel()
      'Exit For
    End If
  Next j
  oDoc = ThisComponent
  DialogLibraries.LoadLibrary("Standard")
  oDialog = createUnoDialog(DialogLibraries.Standard.Dialog1)
  oListBox1 = oDialog.getControl("ListBox1")
  PutClasses(oItemDoc.getSheets().getByName("Sheet1"))
  oDialog.execute()
  oDialog.dispose()
  End
  Error:
    resume next
End Sub
Sub PutClasses(oLocSheet As Object)
Dim oCursor As Object
Dim i As Integer
Dim sCells() As String
  sCells() = Array("A2", "C2", "E2")
  Dim sClasses(UBound(sCells())) As String
  
  For i = 0 To UBound(sCells())
    sClasses(i) = oLocSheet.getCellRangeByName(sCells(i)).getString()
  Next i
  oListBox1.removeItems(0,oListBox1.getItemCount())
  oListBox1.addItems(sClasses(),0)
End Sub

あとは,分類表を変更したときの処理を記述しなければいけませんね。

リストボックスのプロパティーやメソッドについては OOoBasic/Generic/obj/ListBox? のページを参考にしてください。

  • はにゃ?? 2005-05-02 (月) 01:29:57
  • 添付ファイルを実行して、うまくいきました。ダイアログのcloseボタンのコードがないのに、ダイアログが閉じるのが不思議でしたがキャンセルをボタンに設定すると閉じるのですね、勉強になります。開いている単価表のシートの指定のしかたも大体わかりました。 添付ファイルでは、セルのデータを配列にしてリストボックスに読込んでいますが、WithとAddItemを使って読込めないでしょうか?(現状のエクセルのマクロでは、そうしているので申し訳ありません)

なお、IE6では右クリックで「対象ファイルを保存」でも、やはりzipになります。 いつも、お世話かけます。宜しく、お願いします。

  • 茶菓? &new([nodate]){date}: Invalid date string;
  • ボタンの種類を OK または Cancel にするとダイアログが閉じられます。そのとき,指定した種類に応じて戻り値が違います。明示的にダイアログを閉じるには,oDialog.endexecute() とします。
Sub PutClasses(oLocSheet As Object)
Dim oCursor As Object
Dim i As Integer
Dim sCells() As String
  sCells() = Array("A2", "C2", "E2")
  oListBox1.removeItems(0,oListBox1.getItemCount())
  For i = 0 To UBound(sCells())
     oListBox1.addItem(oLocSheet.getCellRangeByName(sCells(i)).getString(),i)
  Next i
End Sub

こんなところでしょうか? With はどのオブジェクトに対して使用するんでしょうか?

  • はにゃ?? 2005-05-02 (月) 12:49:33
  • With はListBox1のオブジェクトです。これは、上記のマクロを参考にしまして自分なりに作成してうまくいきました。  また、ListBox1から分類項目を選択することで、ListBox2に品名を読込むマクロも作成してうまくいきました。現在は、ListBox2で品名を選択したら見積書の品名項目セルに単価表の品名を、単価項目セルに単価表の単価を書き込むマクロを作成中です。選択しているセルの見積書の品名のセルに単価表の品名を読込むところまでは、なんとかマクロを作成しました。今は、見積書の単価項目に単価表から読込むところを作成中です。有難うございます。
  • 茶菓? &new([nodate]){date}: Invalid date string;  
  • もうすぐ完成でしょうか?完成したら教えていただけますか?このページも解決になりそうですね -- はにゃ?? 2005-05-03 (火) 01:10:11
  • いろいろ試したのですが、またお世話になります。品名の記入は、 ThisComponentCurrentSelection.String = 単価表の品名セル でうまくいきました。品名項目の右のセルが単価項目なのですが、エクセルでの ActiveCell.Offset(0,1).Value = 単価表の金額セル に相当するcalcのマクロはないのでしょうか?宜しく、お願いします。連休中なのに失礼します。
  • 茶菓? &new([nodate]){date}: Invalid date string;
  • Offset に対応するメソッドがないので,セルのアドレスを取得してそのアドレス +1 とするといいと思います。

セル範囲の RangeAddress プロパティーでセル範囲のアドレスに相当する行および列の開始位置と終了位置のインデックスが取得できます。

com.sun.star.table.CellRangeAddress struct
Sheetシート
StartColumn開始列
EndColumn終了列
StartRow開始行
EndRow終了行
Sub Main
  MsgBox ThisComponent.CurrentController.getSelection().RangeAddress.StartColumn
End Sub

上記のように試してもらえると分かると思います。

getSelection() メソッドで取得できるのはセル範囲だけではないことに注意が必要なのですが,アクティブセルは選択セル範囲の左上のセルに相当するので (OOo では) StartColumn および StartRow を使います。

(セルの指定が OOo では "列, 行" の順なので注意が必要ですが。)

  • はにゃ?? 2005-05-03 (火) 10:47:44
  • どうでもいいかもしれませんが,OOo の getSelection メソッドでは選択セルや選択セル範囲以外のオブジェクトまで取得ができます。というか,セル範囲の取得のみに使用することができません。たとえば,図形描写や画像を張り込んでいる場合にそのオブジェクトが選択状態であればそのオブジェクトが getSelection メソッドで取得されます。

取得したオブジェクトの ImplementationName などを確認するなどでエラーを回避するしかありませんが。

  • はにゃ?? 2005-05-03 (火) 11:00:05
  • なんとか、単価の記入マクロも動くようになりました。どうも、有難うございます。 エクセルとは、かなり違うところがあり大変でした。品名の記入のときも、単価が記入されたり。セルの指定が、逆なんですネ!。今度は、単価表の品名のセルのアドレスを指定しなおしたら、品名が記入されない。エクセルでは、数値も文字列も "Value" でいいのが、calcでは "String" と "Value" を区別しなければならないんですネ!。 "MsgBox" では、品名が表示されるのになんで記入できないのか悩みました。 また、セルもリストボックスも最初の位置が、 "0" なんですネ!。いろいろ、書いてもきりがないのでこの辺にしておきます。 いろんなアドバイス、どうも有難うございます。
  • 茶菓? &new([nodate]){date}: Invalid date string;
  • じゃあ、解決でしょうか?ステータスを解決に変更しておきます。毎回、回答を書くのが遅くてすいませんでした。そろそろ、移植時の注意点等についてまとめたページを作成した方が良くなってきましたね。あとで作ろうかと思います。 -- はにゃ?? 2005-05-03 (火) 15:32:27
  • 解決にもしていただいて、有難うございます。今後もよろしくお願いします。-- 茶菓? &new([nodate]){date}: Invalid date string;

 


Attach file: file見積書.sxc 1153 download [Information] file単価表.sxc 972 download [Information] fileOOobbs62-1.sxc 1121 download [Information] fileestimate.sxc 1022 download [Information] fileestimate-2.sxc 979 download [Information] fileunit_value.sxc 1116 download [Information]

Reload   New Lower page making Edit Freeze Diff Upload Copy Rename   Front page List of pages Search Recent changes Backup   Help   RSS of recent changes