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

Q&A集[?]

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

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

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

質問コーナー

サイト内検索

分類メニュー

関連サイト


本日:1
昨日:1
総数:2798
現在:3


マクロの画面更新の停止

ページOpenOffice.org FAQの登録ページ
投稿者匿名
分類
edit/refer
優先順位
edit/refer
状態
edit/refer
カテゴリー
edit/refer
投稿日2009-10-31 08:56:33 (土)
OSWindows XP
依存するページ
バージョン
edit/refer

メッセージ

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

Excelの画面更新の停止は『Application.ScreenUpdating = False』で行えます。

OOo Basicでは『ThisComponent.LockControllers()』や『ThisComponent.addActionLock()』で停止できるとの記述を見かけましたが、うまくいきません。
Excelで作成していたマクロをなんとか移行したのですが、画面は動くは動作は非常に遅いはで困っています。

どこにどのように記述すれば良いか教えていただきたいです。

初歩的なことで申し訳ないのですが、よろしくお願いします。


OOo はドキュメント単位

K.Tsunoda (2009-10-31 13:45:26 (土))

Excel/VBA では Application.〜 ですから、Excel全体に作用します。

OOo.Basic では ThisComponent.〜 ですから、ドキュメント単位で機能します。

例えば、A.ods 内のマクロから B.ods を更新する際に
ThisComponent.LockControllers と記述していたら機能しません。この場合、
(B.odsのドキュメントオブジェクト).LockControllers と書く必要があります。

この辺りを確認してみてください。

ありがとうございます

匿名 (2009-10-31 16:57:12 (土))

同じファイル内でのマクロになりますのでThisComponent.addActionLock()で問題ないかと思っています。(よくわからないので両方記述しています。)がうまく行きません。

なにか根本的に間違っているのでしょうか??

ちなみにVBA Supportを用いていてVBAの記述とOOoのBasicの両方の記述があります。

VBASupport 1 も中身は同じ

K.Tsunoda (2009-10-31 17:26:30 (土))

VBASupport 1 配下での[Application.ScreenUpdating]を実行する
OOo のソースを閲覧してみましたが、行なっている事は
カレントドキュメントに対する LockControllers/UnlockControllers です。

> 画面は動くは動作は非常に遅いは
処理はセルへの書き出しでしょうか?

更新対象のオブジェクトによって効き目が違うのかもしれませんが、
少なくともセル書き出しには効果ある筈です。

そうですか…

匿名 (2009-10-31 17:35:20 (土))

セルへの書き出しがよく理解出来ていないのですが…条件にあうものを選択して別シートに貼り付ける作業を行っています。

単に画面のちらつき(更新)を抑えたいのですが、それには難しいのでしょうか?

マクロにもよる

K.Tsunoda (2009-10-31 18:21:49 (土))

例えば、「マクロの記録」を元にした下記のような Select 使いまくりなマクロの場合
Excel では ScreenUpdating の効果はありますが、
OOo では、ある程度まとまった回数分の
画面更新が止まったり進んだりと面白い動きをします。

Option VBASupport 1
Sub Main1
Dim i As Long
Application.ScreenUpdating = False
For i = 1 To 500
    Worksheets("Sheet1").Activate
    Worksheets("Sheet1").Cells(i, 1).Select
    Selection.Copy
    Worksheets("Sheet2").Activate
    Worksheets("Sheet2").Cells(i, 3).Select
    Worksheets("Sheet2").Paste Destination:=Selection
Next i
Application.ScreenUpdating = True
End Sub


これを下記のように直すと最後まで画面更新は止まります。

Option VBASupport 1
Sub Main2
Dim i As Long
Application.ScreenUpdating = False
For i = 1 To 500
  Worksheets("Sheet1").Cells(i, 1).Copy _
    Destination:=Worksheets("Sheet2").Cells(i, 5)
Next i
Application.ScreenUpdating = True
End Sub

ありがとうございます

匿名 (2009-11-01 00:40:54 (日))

並び替えをしてあるシートを下から順に比較をしていって条件に合わなくなったら条件に合っていたものをすべて新規のシートに切り取って貼り付けるようなのを作成したのですが、Selectを多用しています。

なんとかSelectを減らすように検討してみます。

ありがとうございます。

確認ですが、Excelのように最初に指定したら解除するまで画面の更新を行わないようにする機能はないということでよろしいでしょうか?

無題

K.Tsunoda (2009-11-01 01:17:29 (日))

たぶん無いと思います。

とりあえず完了にします

M.Kamataki (2009-11-01 22:33:51 (日))

K.Tsunodaさん、いろいろありがとうございます。

区切りの良いところで、とりあえず完了にしておきます。

完了にはなってますが…

匿名 (2009-11-02 12:17:14 (月))

Selectを多用していた部分を別の記述に書き換えましたが、大して速度に違いがありませんでした。

お手数ですが、添削していただけないでしょうか?
シート名がcnv02でC列にある項目をシートに振り分けるものです。

Excelの場合は数秒で完了するのですが、この場合2分強掛かります。

なお、OOo.Basicの記述は全く理解していないので自動記録のものをそのまま流用しております。

無題

tani (2009-11-02 15:13:06 (月))

試してないので勘ですが、↓がなんかよくない気がします。

Sheets("cnv02").Select                                                          '一番下から順にラインコードが変わるまで検索
r1 = Range("A65536").End(xlUp).Row
c1 = Range("A65536").End(xlUp).Column
While Cells(r1,c1).Offset(, 2) = Cells(r1,c1).Offset(-1, 2)
  r1 = r1 - 1
Wend

このへんの計算を、Do Untilループに入る前に事前にデータを配列に入れておいて、配列の計算にするようにしたら、ぐっと早くなるような気がします。
http://api.openoffice.org/docs/common/ref/com/sun/star/sheet/XCellRangeData.html

無題

K.Tsunoda (2009-11-02 17:15:20 (月))

テストはしていません。
敢えて出来るだけ原型を残す修正にしました。

> Dim r1 As Integer
> Dim c1 As Integer
行番号を扱うなら Long です。Integer(Max 32767)では 65536 はオーバーします。
列番号は256までですが、合わせて Long にしておいた方が良いでしょう。

> c1 = Range("A65536").end(xlUp).Column
A列で処理しているんですから、c1 = 1 で固定でしょう。

> While Cells(r1, c1).Offset(, 2) = Cells(r1, c1).Offset(-1, 2)
⇒ While Cells(r1, c1 + 2) = Cells(r1 - 1, c1 + 2)
⇒ While Cells(r1, 3).Value = Cells(r1 - 1, 3).Value

> While Cells(r1, 3).Value = Cells(r1 - 1, 3).Value
> r1 = r1 - 1
> Wend
> Range(Cells(r1, 1), Range("a65536").end(xlUp).end(xlToRight)).Cut
r2 を用意して、r1 の値を残せば、ここで再び end(xlUp) は不要でしょう。

r2 = r1
While Cells(r2, 3).Value = Cells(r2 - 1, 3).Value
  r2 = r2 - 1
Wend
Range(Cells(r2, 1), Cells(r1, 1).end(xlToRight)).Cut


行によって使用範囲(列)が変わるんでしょうか?
切取り列範囲(右側)が固定ならend(xlToRight) も不要でしょう。
(コードを見るとK列までじゃないんですか?)

Range(Cells(r2, 1), Cells(r1, 11)).Cut  'K列: 11(VBA)


Sheets("cnv02").Select
r1 = Range("A65536").end(xlUp).Row
r2 = r1
While Cells(r2, 3).Value = Cells(r2 - 1, 3).Value
  r2 = r2 - 1
Wend
Range(Cells(r2, 1), Cells(r1, 11)).Cut
add_sheet



OOo.Calc はセルを1つ1つ取り出して処理するのが、Excel と比べるのが
失礼なくらいに、べらぼうに【遅い】です。
tani さんが言うように配列に取り出してから処理しないと使い物になりません。

Dim vntWK As Variant
Sheets("cnv02").Select
r1 = Range("A65536").end(xlUp).Row
'vntWK = Range("A1:C" & r1).getDataArray  'Excel記法+ getDataArray はNG
vntWK = ThisComponent.Sheets.getByName("cnv02").getCellRangeByName("A1:C" & r1).getDataArray
r2 = r1
While vntWK(r2 - 1)(2) = vntWK(r2 - 2)(2)  '配列はゼロから
  r2 = r2 - 1
Wend


セル範囲を配列に取り出す場合の配列の形態が Excel と Calc では異なります。
http://blog.livedoor.jp/addinbox/archives/51265222.html

ありがとうございます

匿名 (2009-11-02 18:01:40 (月))

理解するのに時間が掛かると思いますが参考にさせていただきます。

やはり不要な部分が多いようですね…
分かる範囲で取り込ませていただきます。

ありがとうございます。

お名前:
題名:


添付ファイル: filesample.bas 946件 [詳細]