tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re: VB6でEXCELのソート
投稿日: 2009/11/26(Thu) 23:17
投稿者魔界の仮面弁士
> Dim objExcel        As Object
> Set objExcel = CreateObject("Excel.Application")
レイトバインドでの実装を行っているようですね。

では一度、Excel への参照設定を外してコンパイルしてみてください。
その状態で、定数(xlAscending等)以外がエラーになるようであれば、
その箇所に、コーディング上の記述ミスがある事になります。


> このエラーをおこさずに何度でもリトライできる方法を教えてください。
http://hanatyan.sakura.ne.jp/vbhlp/excelframe.htm
の「(最初に必ずお読み下さい)」「(こちらも合せてお読み下さい)」をご覧下さい。


>     'Excelを起動
>     Set objExcel = CreateObject("Excel.Application")
ここで、Excel を一つ起動していますね。

>     Set objBook = objExcel.Workbooks.Open(txtExcelPath.Text)
そしてここでは、その起動したExcelの Workbooks を操作しています。

> '----START
>     Cells.Select
では、ここでいう「Cells」とは、どの Excel のどのブック上のセルでしょうか?

「objBook.Workbooks(1).Cells.Select」などであれば、最初のワークシート上の
全セルを選択状態にする、という事が明らかになります。

しかし単に「Cells.Select」と書いただけでは、どのオブジェクトを操作するかが
曖昧になってしまっているわけです。Excel VBA であれば、自シート上のセルで
ある事が明らかですが、外部(VB6)から操作する場合はそうはいきません。


なお、VB6 から Excel を参照設定しておらず、しかも Option Explicit の場合には、
「Cells.Select」だと、Cells が“変数は宣言されていません”のエラーになります。
しかし「〜.Cells.Select」として、どのオブジェクトを操作しているのかを
正しく記述していれば、そうしたコンパイルエラーが発生する事もありません。
(なので、参照設定をあえて外す事も、問題点の発見の役に立ちます)


分かりにくいのは、今回のように Excel を参照設定していた場合ですね。
親オブジェクトを記述していない“間違ったコード”であっても、初回実行時には
グローバルオブジェクト経由で操作できてしまうのですが、Excel を起動しなおすと、
最初に起動していた方と、二回目の Excel のうち、どちらを操作するのかが曖昧に
なってしまい、問題が生じるわけです。また、このようなコードは、アプリ終了後も
非表示の Excel プロセスが解放されずに残ってしまうなどの弊害を伴います。

親オブジェクトを明示し、曖昧さを排除すれば、参照設定の有無に関わらず、
問題無く動作するようになります。


>     Selection.Sort Key1:=Range("C2"), Order1:=xlAscending, Key2:=Range("D2") _
>         , Order2:=xlAscending, Key3:=Range("G2"), Order3:=xlAscending, Header:= _
>         xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
>         SortMethod:=xlPinYin, DataOption1:=xlSortTextAsNumbers, DataOption2:= _
>         xlSortTextAsNumbers, DataOption3:=xlSortNormal
こちらも同様です。

「Selection」が、どのオブジェクトの選択領域を指しているのか、
「Range」が、どのブック上の範囲を示しているのか示されていません。

たとえば、Range("C2") ではなく、〜.Range("C2")。
Selection ではなく、objExcel.Selection などのように、
曖昧さを無くす記述をすれば、今回の問題は解決するはずです。


ただし、さらに言えば、そもそも Select や Selection を使ったコードを
多用するべきではありません。マクロ操作で自動生成されるコードでは、
まず選択ありきなので仕方無いのですが、VB にするときはシート名や範囲名を
明示したり、それらを変数で受けて利用する事を心がけてください。


たとえば普段、VB6 の操作でも
 Form2.Text1.Text = "TEST"
などとは書いても、
 Form2.SetFocus
 Screen.ActiveForm.Text1.SetFocus
 Screen.ActiveControl.Text = "TEST"
なんて書き方はしませんよね。

それと同じことで、
 objSheet1.Cells.Select
 objExcel.Selection.Sort Key1:=objSheet1.Range("C2"), 〜
などと書く必要は無く、
 objSheet1.Cells.Sort Key1:=objSheet1.Range("C2"), 〜
あるいは
 objSheet1.Cells.Sort objSheet1.Range("C2"), 〜
などと直接書けば済むという事です。

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。