Top > OOobbs2 > 78

OOobbs2/78 Edit

  • サマリ: 正規表現でセル内の文字列にアクセスしたい
  • 環境: Basic
  • 状態: 解決
  • 投稿者: kolona?
  • 投稿日: 2007-10-17 (水) 03:04:02

質問 Edit

OpenOffice.orgのBasicでマクロを組んでいるのですが、 どうしてもやり方が解らない部分があるので質問させていただきます。

http://hermione.s41.xrea.com/pukiwiki/pukiwiki.php?OOoBasic%2FCalc%2Fcellcursor http://hermione.s41.xrea.com/pukiwiki/pukiwiki.php?OOoBasic%2FCalc%2Fsearch

上のURLを参考にしながら、

1. 特定の文字列を含むセルを正規表現で探す

2. 指定したセル内の一部の文字列に特別に書式を適用する

というマクロを作成しています。

例えば正規表現で ^A[Rr]$ を探し、 一文字目を青文字、二文字目をRなら黄色文字、rなら緑色文字にするといった作業を行うマクロです。

下に作りかけのマクロを示します。正規表現でマッチもでき、セルを特定するとこまではいけます。しかし、テキストカーソルを使ってセルの中の文字列に対して正規表現マッチをしたいのですが、メソッドが見つかりません。とりあえず、テキストカーソル関係のメソッドを WritedbgInfo( oTextCursor ) で書き出して精査したところ、

SbxINTEGER compareRegionStarts ( SbxOBJECT, SbxOBJECT ) 
SbxINTEGER compareRegionEnds ( SbxOBJECT, SbxOBJECT ) 

の二つがそれらしい名前のメソッドでした。しかしながら、引数になっている SbxOBJECTはどういったメソッドでつくるのか、皆目見当が付きません。

これらのメソッドを「compareRegion openoffice」などのキーワードでgoogle検索してみても4件しかヒットしませんし、「openoffice テキストカーソル 正規表現」等のキーワードで検索しても目的の情報は得られませんでした。

前置きが長くなりましたが、私が知りたいのは、

1. compareRegionStarts の使い方

2. 正規表現でセル内の文字列にアクセスできる他の方法

の2つになります。どなたか詳しい方、ご教授願います。

あと、OpenOffice.orgはまだ書籍がほとんど出ていないので(特にマクロに関して)、 StarSuiteの取説つきパッケージを買おうかと考えています。 StarSuiteの製品版をお持ちの方、こいつの取説が役に立つか、私見で良いので情報下さい。 以下に作りかけのマクロを示します。

REM 特定の文字列を探して一部の文字列に特別に書式を適用する
REM 
Sub string_format_set_string
 
 Dim cell1,cell2 As Object
 Dim oSheet As Object
 Dim oDocument As Object, oFound,oSearchDesc As Object
 Dim oTextCursor As Object
 
 oDocument=ThisComponent
 oSheet=ThisComponent.CurrentController.ActiveSheet 
 oSearchDesc = oSheet.createSearchDescriptor()
 REM 正規表現を使う
 oSearchDesc.SearchRegularExpression = true
 REM 単語単位での検索をしたい
 REM oSearchDesc.SearchWords = true
 REM 大文字と小文字を区別するときはtrueに設定
 REM oSearchDesc.SearchCaseSensitive = true
 REM 検索する文字列
 oSearchDesc.SearchString = "^A[Rr]$"
 
 oFound = oSheet.findFirst ( oSearchDesc )
 if IsNull(oFound) <> 1 Then
  oTextCursor=oFound.createTextCursor()
  Globalscope.BasicLibraries.LoadLibrary( "Tools" )
  'Globalscope.BasicLibraries.LoadLibrary( "Tools" )
  WritedbgInfo( oTextCursor )
  'DbgInfo2sheet( oTextCursor )
  oFound.charcolor=RGB(0,0,255)
 endif
 
 Do While NOT IsNull( oFound )
  oFound = oSheet.findNext( oFound, oSearchDesc )
  if NOT(IsNull(oFound)) Then
   oFound.charcolor=RGB(0,0,255)
  end if
 Loop

End Sub

回答 Edit

  • compareRegionStarts の使い方

二つのメソッドは com.sun.star.text.XTextRangeCompare インターフェースのメソッドです。これらは二つの TextRange の位置関係を調べるためのものです。フィールドなどをよく利用する Writer ではときどき使われます。

compareRegionStarts ( [in] .text.XTextRange xR1, [in] .text.XTextRange xR2 )
compareRegionEnds   ( [in] .text.XTextRange xR1, [in] .text.XTextRange xR2 ) 

返り値は以下のようになります。Starts は開始位置同士、Ends は終了位置同士がひかくされます。

  • 1: xR1 が xR2 より前で始まっている(または終わっている)
  • 0: xR1 と xR2 が同じ位置で始まっている(または終わっている)
  • -1: xR1 が xR2 より後ろで始まっている(または終わっている)

例を書こうと思ったのですが、Calc だと IllegalArgumentException で使えませんでした。Writer だと同じ書き方でいけるんですけどねぇ。これらのメソッドは二つのテキスト範囲の位置関係を調べるためのもので、テキストに含まれている文字列の比較は出来ません。

  • はにゃ?? 2007-10-17 (水) 12:11:50
  • セル内で正規表現

簡単なメソッドでセル内の文字列を正規表現で一致する方法はありません。セル内の文字列を取得して正規表現で一致させるしかありません。しかし、OOo Basic だと正規表現が利用できるランタイム関数がありません。

方法は以下のどれかになります

  1. TextSearch を使う
  2. 別の Python、Javascript、Java、BeanShell などのコードで一致させる
  3. いっそのこと別の言語に乗り換える

文字の色を変えるということであれば、どの場合も文字列から一致する文字の位置を調べてセルカーソルを移動、文字の色を変えることになります。

1 の TextSearch にはバグなのかサブパターンがうまくいきません。(ref ではサブパターンがあるときには・・・となっていますが、実際には全体に一致したものしか戻りません。)

使い方ですが、たとえば

ABCDEFG

のセルの文字列に正規表現 "C." で一致させるとすると。

Sub Main
  oDoc = ThisComponent
  oSheet = oDoc.getSheets().getByIndex(0)
  oCell = oSheet.getCellByPosition(0,0)
  sTxt = oCell.getString()
  
  oTextSearch = CreateUnoService("com.sun.star.util.TextSearch")
  aOptions = CreateUnoStruct("com.sun.star.util.SearchOptions")
  With aOptions
    .algorithmType = com.sun.star.util.SearchAlgorithms.REGEXP
    .searchFlag = com.sun.star.util.SearchFlags.REG_EXTENDED
    .searchString = "C."
  End With
  oTextSearch.setOptions(aOptions)
  aResult = oTextSearch.searchForward(sTxt,0,Len(sTxt) -1)
  If aResult.subRegExpressions = 1 Then
    oCursor = GetTextCursorRange(_
      oCell,aResult.startOffset(0),aResult.endOffset(0))
    msgbox oCursor.getString()
    'oCursor.CharColor = -1
  End If
End Sub


Function GetTextCursorRange(oCell,nStart,nEnd) As Object
  oCursor = oCell.createTextCursor()
  With oCursor
    .gotoStart(False)
    .goRight(nStart,False)
    .goRight(nEnd - nStart,True)
  End With
  GetTextCursorRange = oCursor
End Function

一致結果 subRegExpressions が >= 1 のとき found です (サブパターンがあると 1 より大きな数値が戻るはずが戻らない)。startOffset と endOffset で一致範囲の開始位置と終了位置が取得できます。

開始位置と終了位置からその範囲のテキストカーソルを取得するには、goRight などで移動させてやります。

2 の方法は文字列の置換などでは使えますが、上記のような場合にはテキストカーソルを取得する部分も同じになってしまうので効果的ではありません。OOobbs2/51#x61c19c1

3 ...

  • はにゃ?? 2007-10-17 (水) 12:50:21
  • StarSuite の古いのしか持っていないので説明書に関しては私は分かりません。持っている方がいらっしゃればお願いします。 -- はにゃ?? 2007-10-17 (水) 14:25:15
  • 丁寧な説明、ありがとうございます。提示してくださったコードを元に、とりあえずTextSearchでできるとこまでやってみます。近いうちにJavaScriptとかに乗り換えるかも知れません。 -- kolona? 2007-10-18 (木) 01:04:17
  • 指針ができたので解決にしたいと思います。でも、StarSuiteの情報持ってる方、是非書き込んでください。 -- kolona? 2007-10-18 (木) 01:10:13
  • Javascript ですか・・・。Python、Javascript、BeanShell、Java の中で一番使われていない気がします。 -- はにゃ?? 2007-10-18 (木) 01:47:09

感想,コメント,メモ Edit

  • WritedbgInfo や DbgInfo2sheet を利用されているようですが、

などをお勧めします。

-- [[はにゃ?]] &new{2007-10-17 (水) 15:18:42};
  • 情報ありがとうございます。MRIを入れてみました。今、使い方を調べています。 -- kolona? 2007-10-18 (木) 01:05:24
  • 使い方が分からなければ掲示板にでも質問してください。MRIは私が作ったものなので、対応できると思います。 -- はにゃ?? 2007-10-18 (木) 01:48:05


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