VB.NET質問スレ

このエントリーをはてなブックマークに追加
10デフォルトの名無しさん
最初は解放の話だったよね。
Finallyで解放するのが普通だとかどうだとか。

ちゅうか、Using使ったらもう戻れません。w
11デフォルトの名無しさん:2007/09/06(木) 14:40:26
非同期例外もとりあえずキャッチしておけばいいとかってあたりは少し怖かった。
いやもちろんキャッチした後、正しくリカバリできるならそれがベストなんだろうけど、
普通はできないでしょ。
12デフォルトの名無しさん:2007/09/06(木) 14:55:29
すいません、質問させていただきます。
.net2003でデータグリッドを使ってファイル操作を行っているんですが、
データグリッド内のTabキーの動きを制限したいんですが、やり方がわかりません。
自分のしたい動きは、Tabを横移動させないで、下にだけ移動させたいんですけど。。。
どなたか教えてください!!
13デフォルトの名無しさん:2007/09/06(木) 14:58:13
RCWはなぜかIDisposableじゃないんだよ。usingは使えない。
ReleaseComObjectを呼ばないとインターフェイスが開放されないと思ってる人が多いが、
ファイナライザでも開放される。
Disposeに対するFinalizeと同じ位置づけで、ある種のフェイルセーフ。
場合にもよるが異常系でのReleaseComObjectはそれほど神経質になる必要はない。
14デフォルトの名無しさん:2007/09/06(木) 15:01:27
つうか、どどねとになってCOM経由でのOFFICE連携は超大変。
丁寧に作る or ラップするクラスを作ってオブジェクト管理しっかりならOKだけどさ。
暗黙のオブジェクトでNGってのはちょっと。

仕事だったら、安定性も考えて市販のライブラリが安い。
15デフォルトの名無しさん:2007/09/06(木) 15:17:34
>>12
KeyDownとかで拾えない?
TabKey押下時、もともとの動きをe.handle=trueでキャンセルして、CurrentCellを現在のCellからRow+1する。
16デフォルトの名無しさん:2007/09/06(木) 18:28:34
>>10
だからそんな話は誰もしてなかったんだよw
かってにそういう話だと思い込んじゃった人が少なくとも一人はいたというだけのこと。

>>13
>ReleaseComObjectを呼ばないとインターフェイスが開放されないと思ってる人が多いが、
>ファイナライザでも開放される。
やっぱりそうだよね

ReleaseComObject読んでおかないとエクセルのプロセスが残る、
とかいう話がまことしやかに言われているが、個人的にはそんな経験は
まったくしたことがないんだよね。

個人的に、この手のことを喧伝してる人はそれ以外のところで
何か妙なことをやっているんだろうなあと思ってる。

あと、こういうことを言う人って何故か「プログラムで作成したエクセルの
プロセスはプログラムで<絶対に>終了しなければならない」という
妙な思い込みにとりつかれていることが多い。
17デフォルトの名無しさん:2007/09/06(木) 18:44:06
いやプロセスは残るだろw
18デフォルトの名無しさん:2007/09/06(木) 18:49:42
>>17
ちょっと説明が舌足らずだったけど、「エクセルのプロセスが残る」という主張を
する人のその言葉の意味は、Application.Quit呼んでエクセルを終了した
はずなのにエクセルのプロセスが残るってことらしいよ。

しかもエクセルを起動したアプリを終了しても残るんだとさ。
19デフォルトの名無しさん:2007/09/06(木) 19:42:39
>>18
プロセスが終了する条件はインターフェイスがすべて開放されてかつ
Workbook.CloseとApplication.Quitの両方が実行されている。
(もちろんWorkbookを開いたり、Addしてない場合はCloseは不要なのだけど)
Quitしてるのに残ってる場合はCloseしてないか見当違いなものをCloseしている。
前スレのソースはそれだった。
20デフォルトの名無しさん:2007/09/06(木) 19:46:10
>>18
JScriptの例だけど、Microsoftの文書で
Application.Quitを呼んでも、参照が残っているとExcelのプロセスは完全に破棄されない。
すぐにExcelのプロセスを終了させるためには参照を破棄するためにガベージコレクション
を強制的に引き起こしてやる必要がある。
と明示的に書かれた記事はある。

ttp://support.microsoft.com/kb/266088/ja

なので、Application.Quitを呼んだだけでは不十分で、その後、速やかに
参照を破棄する、というのは正しいのではないの?

>しかもエクセルを起動したアプリを終了しても残るんだとさ。
これは分からない。
Application.Quit読んでれば問題ないと思うけどね。
21デフォルトの名無しさん:2007/09/06(木) 19:46:37
以下の関数をXPで実行するとIPV4の文字列が返って来るのに
Vistaで実行するとIPV6の値が返ってきてしまいます。
なんとかIPV4のほうのアドレスを取得できないものでしょうか?

Public Function GetLocalIpAddress(Optional ByVal ipNo As Integer = 0) As String
  Dim temp As System.Net.IPAddress() = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName).AddressList
  If temp.Length <= 0 Then
    Return System.Net.Dns.GetHostName & ":IpUnKnown"
  Else
    Return temp(temp.Length - 1).ToString
  End If
End Function
22デフォルトの名無しさん:2007/09/06(木) 20:17:33
>>21
V4, V6あったらV6が優先されるようだからそうなるのかな。
Dns.GetHostAddressesなら両方戻ってくるはず。
23デフォルトの名無しさん:2007/09/06(木) 20:31:44
>>20
>なので、Application.Quitを呼んだだけでは不十分で、その後、速やかに
>参照を破棄する、というのは正しいのではないの?
それはたぶん正しいと思う。
疑問なのはReleaseComObjectが本当に必要かどうか。

エクセルを起動したアプリを終了してもエクセルのプロセスが消えない問題は
VB6の時は確かにあった。

ドトネドでは、たとえばメソッド内で使う一時的なオブジェクトでも必ず変数に
入れて使用後はそれにNothingを入れる、というような面倒なことをしなくても
そういった問題は経験してないなあ。
24デフォルトの名無しさん:2007/09/06(木) 20:38:20
>>22
レスありがとうございます。

どうやらGetHostAddressesを調べながらテストしてみたら
もとの提示したサンプルでもIpAddressのArrayの中の一つにV4形式のアドレスがあるようでした。

これってVistaのV4を切っていなければ必ず入っているものなんでしょうか・・・・
とりあえずIPV4が有効なことを前提に、ループで回して適当な正規表現を取得してみることにします。

25デフォルトの名無しさん:2007/09/06(木) 20:42:52
参照の破棄なんかいらんよ大抵は
その場でガベージコレクションするなら別だが

問題なのはガベージコレクションじゃ実際にいつ解放されるのか分からんて事だ。
26デフォルトの名無しさん:2007/09/06(木) 20:46:13
ファイナライザで解放されるってのもみんな分かってると思うが。
たんにそれがあまり望ましい動きじゃないってだけで
27デフォルトの名無しさん:2007/09/06(木) 20:48:47
>>11
そんなこと誰も言ってなかったぞ?
勘違いしてたやつはいたみたいだが…
28デフォルトの名無しさん:2007/09/06(木) 20:57:50
Try内でリターンしてもFinallyは実行されるという動作を理解してない人もいるということ
29デフォルトの名無しさん:2007/09/06(木) 21:02:01
かといってガベージコレクションを明示的に呼ぶのもあんまりしたくないから
結局まっとうな手段としては漏れなく解放してやるしかない

はっきりいってあまり現実的じゃないから
ガベージコレクションでごまかしたくなる
開発者に徹底するなんてまず無理だもんorz
30デフォルトの名無しさん:2007/09/07(金) 07:54:19

ListView のカラムの移動について教えてください。

ListView で、カラムを摘んで別のカラム位置にD&Dして移動することができましたが、
これで ListView.ColumnReordered イベント が発生しますが、

そこで ColumnReorderedEventArgs.OldDisplayIndex プロパティ や 同NewDisplayIndex プロパティ
を知ってカラムの並び順を記憶する配列などを更新することができ、

それを使って、次回にその並び順に Columns (=ColumnHeaderCollection クラス ) の
メンバーItemを並べ替えることはできるのですが、

それだけですと、データ部の ListViewItem の各カラムはそれに伴って同様に移動しては
くれませんでした。

この場合、このデータ部分のカラムもいっしょに移動する(D&Dで移動するのと同じ効果)
方法はありますでしょうか? よろしくお願いします。
31デフォルトの名無しさん:2007/09/07(金) 08:24:36
>>30
が、が、が、
こういう日本語使う人ってたまにいるね。

君はListViewItemtというものを根本的に勘違いしてないか?
おまけにどうしようもなく知恵がない。
カラム(ヘッダ)の順番が分かっているなら、カラムの順番に対応して
サブアイテムを設定するだけだと思うんだが。
32デフォルトの名無しさん:2007/09/07(金) 08:25:30
>>31
訂正
×ListViewItem
○ListView
33デフォルトの名無しさん:2007/09/07(金) 08:36:40
>>31
>カラム(ヘッダ)の順番が分かっているなら、カラムの順番に対応して
>サブアイテムを設定するだけだと思うんだが。

確かにその通りで、ListViewItem.ListViewSubItemCollection クラス の説明をみますと
そのように行うことが可能なようなのですが、D&Dで一発で実行されていることを考えると
どうも一発系のメソッドかプロパティがあるのでは・・・・・?と思ったのです。

もう一度Helpを探してみてもどうやら見つからないところを見ると、やはりおっしゃるように
ひとつひとつ ListViewItem をForループで回して対応するしかないのかもしれないです。

ものすごく大量の ListViewItem があった場合に時間がかかりそうなのも懸念された
のですが、それしか方法がない場合はしかたないですね、とりあえずこれでやってみる
ことにします。ご指導どうもでした。
34デフォルトの名無しさん:2007/09/07(金) 08:54:17
もう、ぷログラミングなんてやめなよ。まっとうじゃないよ
35デフォルトの名無しさん:2007/09/07(金) 08:57:28
>>34

やっぱりもっといい方法あるでしょうか。それ知りたいのですが、よろしければ
ご指導をよろしく。
36デフォルトの名無しさん:2007/09/07(金) 09:00:23

実際、Explorer ではちゃんと実現されているので、やはり簡単にできるのではとは
思っているのですが、どうも Help が読みこなせていないのかもしれません。

やはり一発系があれば知りたいのですが・・・
37デフォルトの名無しさん:2007/09/07(金) 12:01:23
>>23
>エクセルを起動したアプリを終了してもエクセルのプロセスが消えない問題は 
>VB6の時は確かにあった。 

VB6でのこの問題はClose/Quit操作漏れの他に、
End命令や捕捉されていない例外で終了した場合にCOMオブジェクト破棄がなされないことにある。
この場合COMオブジェクトがアウトプロセスサーバーの場合はそのプロセスが残る。
一方、全フォームがUnloadか閉じるで終了した場合は後処理でオブジェクトの破棄はなされる。

COMへの参照をグローバルやstatic変数に置くとNothingを設定しない限り
終了時まで参照が残るため、Endで終了した場合は後処理が省かれプロセスが残ってしまう。
さらにFormの暗黙のインスタンスの問題がある。Formで暗黙のインスタンスを使った場合、
そのFormのインスタンスはUnload(閉じるを含む)したとしても、プロセスの終了まで破棄されない。
ただしUnload(閉じるを含む) とSet Form1 = Nothingの両方の操作を行った場合は破棄される。
このためFormのフィールドにCOMの参照を置いた場合もグローバルやstatic変数に置くのと
同じ問題が発生する。あとケースとしてはまれだが循環参照があった場合も同様。
38デフォルトの名無しさん:2007/09/07(金) 12:05:42
>>37 続き

VB.NETの場合はEnvironment.Exitで終了しても未補足の例外で異常終了した場合も
オブジェクトの終了処理はなされるので問題はおきにくい。
例外はCLR自体が~C操作やOS側の例外での終了した場合。

Formの暗黙のインスタンスはVB6と似た動きをするので早期に参照を破棄したい場合は
同様の注意が必要になる。
暗黙のインスタンスではForm1のメソッドにアクセスする時に、
Form1が初期状態(Nothing)または既にDispose(Close)された状態であれば
新規にForm1のインスタンスを生成してForm1に設定する。
VB6と違ってUnload(Dispose)後の再利用はしないが、
参照が破棄されるのは次のForm1を新たに操作し始めたタイミングになる。
Dispose後速やかにGCの対象にするためにはSet Form1 = Nothingの操作が必要になる。