[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 1001- 2chのread.cgiへ]
Update time : 12/14 12:55 / Filesize : 253 KB / Number-of Response : 1002
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

Excel VBA質問スレ Part5



1 名前:デフォルトの名無しさん [2007/12/12(水) 17:27:44 ]
ExcelのVBAに関する質問スレです

質問前に 【 >>2-3 】 あたりを良く読むこと

前スレ
pc11.2ch.net/test/read.cgi/tech/1189814602/

481 名前:デフォルトの名無しさん [2008/01/24(木) 10:37:07 ]
>>478です。
何度もすみません。もうこのスレに書いてしまったので、
ほかのスレに書いたら、マルチポストとか云うのに
なってしまいますので、もしよろしければこのスレで
教えて頂けないでしょうか?

482 名前:デフォルトの名無しさん mailto:sage [2008/01/24(木) 11:04:47 ]
>>481
誤爆はマルチにはならないと思うよ。
マルチポストだって言うヤツは居るかもしれんが、普通に教えて貰えると思う。
俺も多少は分かるけど、このスレで回答したくない。回答が違ってても突っ込みがなさそうだから。


483 名前:デフォルトの名無しさん [2008/01/24(木) 11:06:44 ]
>>482さん。
ありがとうございます。
助かりました。

484 名前:デフォルトの名無しさん [2008/01/24(木) 12:07:30 ]
AutoFilterが設定されたシートで選択されたセルの行数を知るには、下記の方法で
出来る事が分かったのですが、もっと簡単な方法がありますでしょうか?

Dim r As Range, rcnt As Long
rcnt = 0
For Each r in ActiveWindow.Selection.Rows
If Not r.Hidden Then
rcnt = rcnt + 1
End If
Next


485 名前:デフォルトの名無しさん [2008/01/24(木) 17:23:24 ]
すいません、VBA超初心者です。
"地域A"というシートから魚名前を検索して個数(魚の名前の2つ下のセル)と総量(個数のセルの1つ右)の数値を
台帳(以下の記述ではシート名”漁獲量”)シートの各魚の行に転記させたいのですが、
一生懸命ヘルプやネット検索しながら自己流で記述しましたが
「オブジェクトは、このプロパティまたはメソッドをサポートしていません。」
と出ます。
どなたか正しい記述をアドバイスしていただけませんでしょうか?

486 名前:485 [2008/01/24(木) 17:24:49 ]
Private Sub CommandButton1_Click()

Dim fish As String
Dim i As Integer
Dim wrkA As Integer
Dim wrkC As Range
Dim wrkB As Range

With Sheets("地域A")
wrkA = .Cells(1, Columns.Count).End(xlToLeft).Column
wrkC = .Range("A1").Resize(1, wrkA)
wrkB = .Range("A3").Resize(1, wrkA)

End With
Dim wrkD As Integer
With Sheets("漁獲量")
wrkD = .Cells(Rows.Count, 1).End(xltoUP).Row
wrkE = .UsedRange
fish = .Range(wrkD, 1).Value
End With


487 名前:485 [2008/01/24(木) 17:25:54 ]
つづきです

For i = 1 To wrkA

If fish = wrkC("wrkA,i") Then
fish = wrkB(1, i)
Cells(wrkD, 1).Offset(0, 1) = wrkB(1, i + 1)

Else
fish = " "
Cells(wrkD, 1).Offset(0, 1) = " "

Exit For
End If
Next i

End Sub

488 名前:デフォルトの名無しさん mailto:sage [2008/01/24(木) 17:55:01 ]
>>485
ちょっと突っ込みどころが多すぎるので、全部回答はできないんだけど、
まだ基本を分かりきってないみたい。
とりあえず、 With Sheets("地域A")   With Sheets("漁獲量")  のトコを
Dim ws As Worksheet    ←もちろん最初(1箇所)だけ
Set ws = ThisWorkbook.Worksheets("地域A")
With ws
のような形に修正すれば、"."キーを押したときに入力補助が反応するから、
それを参考に修正するといいと思う。この入力補助が反応するようなコードってのは結構重要。
("."を押してもメソッドが出なければ、記述したところでほとんど実行時エラーになる)

あとは、.End(xltoUP) の定数は xlUp がいいのと、
fish = .Range(wrkD, 1).Value の行みたいに、Cells と Rangeの使い分けが混乱してるかな。


489 名前:485 [2008/01/24(木) 18:00:49 ]
>>488
どうもありがとうございます!!
突っ込みどころ満載ですか…笑
ご指摘を元に再度勉強してがんばってみます!!



490 名前:488 mailto:sage [2008/01/24(木) 18:30:38 ]
>>489
ゴメン、もっと重要なポイントがあった。
wrkC = .Range("A1").Resize(1, wrkA) は、オブジェクト型変数への代入になるので、
Set wrkC = .Range("A1").Resize(1, wrkA) という書式を必ずとること、です。


491 名前:デフォルトの名無しさん mailto:sage [2008/01/25(金) 09:36:51 ]
漁獲量・・・

492 名前:デフォルトの名無しさん mailto:age [2008/01/25(金) 23:56:11 ]
すみません。vlookupのワークシート関数がうまく動きません。
普通のvlookupのようにvlookup(値、範囲、2、False)としましたが
エラーが出てしまいます。範囲がおかしそうですが
どう書き方が誤っているのかがよく判りません。
どなたか、御指摘願えませんでしょうか?

With Worksheets(2)
'Xは適当な自然数です。
For i = 1 To 100
Cells(i + 1, 2) = Application.VLookup(Cells(1, 1).Offset(i, 0).Value, .Range(Cells(2, 3), Cells(X, 4)).Address, 2, False)
Next i

493 名前:デフォルトの名無しさん mailto:sage [2008/01/26(土) 01:11:11 ]
すみません。色々試行錯誤していたら解決しました。有難うございました

494 名前:デフォルトの名無しさん [2008/01/26(土) 17:35:21 ]
かなり高度な質問です。
Me.Controls.Add("Forms.textbox.1","品名",True)
のFormsって一体何なのですか?

495 名前:デフォルトの名無しさん mailto:sage [2008/01/26(土) 17:48:24 ]
余りに低レベルなので泣けてきました。

496 名前:デフォルトの名無しさん mailto:sage [2008/01/26(土) 17:52:19 ]
OLEコントロールの名称でないの。
Microsoft Forms 2.0 TextboxのPROGID

497 名前:デフォルトの名無しさん [2008/01/27(日) 13:51:07 ]
VBAの中でソルバ関数を実行しようとしてます。
その目的セルの評価値を計算する際に、さらにソルバを実行したいです。
(つまりソルバの2重ループになる感じ)

が、これを実現できなくて困っています。
考えてたのは、内側のループのソルバ部分を関数にして
ワークシートから呼び出せるようにして、
それを外側ループのソルバの目的セルの数式に放り込んでやればいい、
という方法なんですけど、
VBAのFunctionの中でソルバをまわそうとすると
シート上の値を書き換えなければならないのでエラーになってしまいます。
かといってそれをサブプロシージャにしても
ワークシート上の数式として表せないので、
結局外側のループで使えません。

何とかこれを達成する妙案はないですかね…
達成したとしても重くて不安定にはなると思うんですが、
それは承知の上です。

環境はWinXP SP2+Excel2000です


498 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 13:57:52 ]
↑根本的に何かを勘違いしてないか?

499 名前:デフォルトの名無しさん [2008/01/27(日) 14:03:45 ]
勘違い・・・っすか
どのへんがおかしいんでしょう?
それすらわからんです



500 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 18:11:32 ]
ソルバ?
ttp://www.joy.hi-ho.ne.jp/ngchsny/xevious_sol.jpg

501 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 23:00:39 ]
Excel2003です。
OnErrorでエラーメッセージの出力を指定しても、

エラーだとそのエラーで無事処理は終わるのですが、
本来エラーにならない場合でも、エラーメッセージ出力→正常処理 となるんですけど。

何か原因は考えられますか?
(プログラム持ち出せないのでここに書けないのです)


502 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 23:16:08 ]
デバッグトレースシテクダサーイ

503 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 00:09:18 ]
>>501
On Error で飛ぶタグの前に Exit Function を書いてなかった、とか言ったら頃すぞ?


504 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 00:49:26 ]
Exit Function を書いてなかった位で殺されるんじゃタマッタもんじゃない。

505 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 01:15:06 ]
マジレスのハズもないのに、
ネタや回答の一つも返さず、つまらんマジツッコミを入れるとは一体どういう了見か?


506 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 01:16:04 ]
>>504
金払って許してもらおうぜ

507 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 10:02:19 ]
うんこ出た
超きもちいい


508 名前:501 mailto:sage [2008/01/28(月) 12:59:32 ]
マクロの最初に

On Error Msgbox
On Error exit Sub

で、以下正常時の処理を記述しているのだが。
Exit Function書くとエラーが出る。

509 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 13:09:09 ]
>>508
そもそもそれコンパイル通るの?
↓なら問題ないと思うけど。

Privete Sub 処理()
 On Error GoTo ラベル
 (通常処理)
 Exit Sub

 ラベル:
 (エラー処理)
End Sub




510 名前:デフォルトの名無しさん [2008/01/28(月) 16:54:46 ]
Sub abc
Dim rng As Range
Set rng = Selection
test rng
End Sub

Function test(r As Range)
Dim c As Range
For Each c Iin r
  'cの処理
Next
End Sub

と選択範囲を引数にしてtestを呼び出しますが、testの引数rはByValにした方がいいんでしょうか?
きちんと動くには動くのですが、ちょっと不安になったもので教えてください。

511 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 17:48:36 ]
>>510
その程度のものを分ける必要があるか知らんが、ByValは無意味。
そこはそのまんま参照渡しが正解。
それよりFunctionは気持ち悪くないかい?
Private Sub test(r As Range)
とするのが普通だろ?
Functionって戻り値を得るものに限定した方がいいと思うが。

512 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 17:52:07 ]
なんだ、下はEnd Subになってるじゃん

513 名前:510 mailto:sage [2008/01/28(月) 19:47:40 ]
>>511-512
すみません、実際は最後はEnd Functionとなってます。
Functionはおかしいんですかねぇ。
それはさておき、実は某所で引数が参照型の場合、ByValが速いとかByRefは気持ち悪いとかいう方がいるんですがどうなんでしょうか?
ご存知でしたらお願いします。

514 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 20:22:33 ]
>>513
byrefだと参照の参照が渡されるから
確かに気持ち悪くて遅いわな。
大差ないけど。

515 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 20:32:01 ]
ByRef の方が遅いのか・・・。 知らなかった。
値渡し=全引数を別アドレスにコピー ⇒ 少し余分に時間が掛かる と思ってた。


516 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 20:40:11 ]
そのsubなりfunctionなりの内部で変更する場合のみbyrefで、
それ以外はbyvalでという方針にしておくのが良い。
(自分で定義したサイズが大きな型は別)

517 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 20:41:15 ]
>>514
なんか勘違いしてない?
実際にやってみたらどうよ。
ByValが速いはずねーだろ?
>>510のおかしなコードじゃ分からないだろうが、なんか戻り値のあるFunctionで試したら?

518 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 20:42:00 ]
>>515
やってみりゃわかるけど、byrefの方が速いよ

519 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 20:43:16 ]
>>514
「参照の参照」という表記が、参照がわかってない証拠。



520 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 20:51:52 ]
ポインタのポインタかよ

521 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 20:53:43 ]
&*p ← キモチワルイ

522 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 21:06:45 ]
俺もやってみたが何度やってもByRefが少し速いな。
Range型の引数でByValが速いケースってどういうケースだ?

523 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 21:27:27 ]
測定誤差

524 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 21:33:15 ]
うちではRangeの場合、ByRefの方がByValの2倍早かった@Excel 2007

525 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 22:28:34 ]
試してみたけど全然違った(Excel 2003)
もちろん、Byrefの方がかなり速い

526 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 22:38:42 ]
エロい方timeGetTimeで測定オナがいしますorz

527 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 22:41:48 ]
軽くぐぐったら、ocamlには「参照の参照」という概念があるらしい。

528 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 22:53:34 ]
>>526
timeGetTimeで計ったが参照私が速かった。
言っとくがtimeGetTimeだって1/1000秒の精度はないからな。

529 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 22:56:30 ]
渡すのは参照の方が早い。実質ポインタ(4byte)だから。
ただその分使用時に一段間接参照のコストがかかるだけ。



530 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 22:57:51 ]
えええ?

531 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 23:06:12 ]
そう言えばExcel総合相談所だったか、それともここだったか忘れたが、Worksheet型の引数をByValにしろなんて
意味不明なこと言ってたやつが前にいたな。彼は勘違いしてるんだろうね。

532 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 23:06:27 ]
基本的にオブジェクト型は参照渡しでいいんです
JAVAと一緒


533 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 23:07:39 ]
なんか思いっきり勘違いしてる人がいない?

534 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 23:08:44 ]
>>533
ちゃんとポイントして指摘しろ

535 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 23:10:19 ]
いや彼にはそのままでいて欲しいからやめとく

536 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 23:25:40 ]
なら最初から黙っとけよ

537 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 23:28:20 ]
センセー、何で一段間接参照が入るのに速くなるんでつか?

538 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 23:32:10 ]
ここVBAのスレだよなぁ?

539 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 23:37:01 ]
ByValでRangeが渡されると、内部で「Set 仮引数 = 実引数(か、それと同等の処理)」
されてるんじゃないの?
だから、使用時に間接参照のコストなんかかからないんじゃ?



540 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 23:45:18 ]
>>539
試せばわかる

541 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 23:47:58 ]
ところで514とか516とか529は試したんだろうか?

542 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 23:54:37 ]
ん、俺516だけど、今回は計測してないよ。
俺のは、多少遅くとも516のポリシーが良いという主張。
VB.NETも、デフォルトByValになったことだし。

543 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 23:59:10 ]
>>542
そっか遅いのは認めるわけね。
ByRefが遅いと書いた514はどうだろう?


544 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 00:00:11 ]
ここまで実計測データ無し。
Excelってベンチマークデータの公表禁止だったっけ?

545 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 00:05:23 ]
>>544
別に禁止じゃねーだろ?
ただみんな自分で計測して分かってると思うけどな
計測してないやつが思い込みでおかしなこと言ってるだけ

546 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 00:08:17 ]
>>518でFAなのに、いつまでやるつもりなんだろう・・・

547 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 00:10:57 ]
>>546
だよな。それ以前に>>511で終わってるわな

548 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 01:56:18 ]
VARIANTをC++から見ての想像。
オブジェクトをByValで渡すと、539の言う通り。オブジェクトへの参照(ポインタ)が渡される。
ByRefだとオブジェクトの変数への参照(ポインタ)が渡される。

いずれにせよ、渡されるのはポインタ値の4バイトだが、
ByValだと参照カウントの処理が要る分、コストがかかるように見える。
一方、ByRefでは2重に間接参照をしなければならないコストがあるはずなので、
測定条件によってどっちが速いかは変わってくるはず。

549 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 02:14:31 ]
>>548
で、どんな時に変わるのよ? 変わる”かもしれん”から一概には言えないってか?




550 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 08:23:45 ]
なんや、盛り上がってたんですねぇ。
乗り遅れたけど、実測データ書いとくね。
>>529が考えにより、ByValが有利になるように5回、引数のcにアクセスしてのr計測だからな。

Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Sub foo()
Dim t(2) As Long, i&, j&
Dim rng As Range
Dim c As Range
Set rng = Range("A:C")
t(0) = timeGetTime
For i = 1 To rng.Count
  Set c = rng(i)
   j = TEST1(c)
Next
t(1) = timeGetTime
For i = 1 To rng.Count
  Set c = rng(i)
  j = TEST2(c)
Next
t(2) = timeGetTime
Debug.Print "TEST1", t(1) - t(0); "ミリ秒"
Debug.Print "TEST2", t(2) - t(1); "ミリ秒"
End Sub

551 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 08:24:50 ]
一般的に、ByRefの間接参照はメモリ読み込み1回が余計に掛かる。
しかし、ByValの内部コピーはメモリ読み書きがそれぞれサイズ(/4)回余計に掛かることになる。
従って、どちらが早いかは自明。

552 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 08:25:03 ]
上の続き

Private Function TEST1(c As Range) As Long
Dim i&, j&
For i = 1 To 5
   j = c.Row
Next
TEST1 = j
End Function

Private Function TEST2(ByVal c As Range) As Long
Dim i&, j&
For i = 1 To 5
  j = c.Row
Next
TEST2 = j
End Function

実測値
TEST1 2448 ミリ秒
TEST2 2528 ミリ秒
5回のループじゃなくて25回くらいならほぼ同じになった。もっと回したらやっと逆転した。
だから>>529の言うことがまったくウソということではないが、通常このように何度もアクセスすることはないから参照渡しで問題なし。
ましてや1回のアクセスに値渡しは無駄もいいとこ。1回なら割合としては上の計測よりもっと差がつく。

553 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 08:27:03 ]
モタモタしてるうちに>>551が間に入ったな。

554 名前:デフォルトの名無しさん [2008/01/29(火) 10:10:38 ]
Mougからきました。
勉強になりました。

555 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 10:51:23 ]
www2.moug.net/bbs/exvba/20080126000019.htm
私もここからきますた。
ビヒネスソフト板以外にExcelのスレがあるとは知らんかった。

556 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 11:41:14 ]
どうみても>>514はあの人だよなぁ。
他のオタクの人たちも既にいると見たがどうよ。

557 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 12:42:38 ]
あまり詮索しないように
どうやら思い違いには気がついたらしいからよかったじゃないか

558 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 12:58:04 ]
なんか気持ち悪い流れとコードだったので、自分で試してみた。(Excel 2000)

*ByRefとByValの違い
 それぞれ1000万回呼び出すのを5回繰り返した場合の平均:
  ByRef: 1654.8ms (A)
  ByVal: 3558.2ms (B)

*「一段の間接参照」があるかどうか
 呼び出した関数内で、次のコードを実行する。
  dim s as string
  s = arg.address (C)
 時間がかかるので、100万回の呼び出しに変更し、それを5回繰り返した場合の平均:
  ByRef: 4488ms
  ByVal: 4660ms
 100万回分の関数呼び出しのコスト(A,Bをそれぞれ10で割ったもの)を引くと、
 (C)のコストが算出される。
  ByRef: 4488-165.48 = 4322.52ms (D)
  ByVal: 4660-355.82 = 4304.18ms (E)

結論:
・ByRefの方がByValの2倍以上速い
・「一段の間接参照」なるものの存在は確認できない(D,Eより)



559 名前:550 mailto:sage [2008/01/29(火) 13:07:28 ]
気持ち悪いコードって俺の?
だったらすまんね。



560 名前:558 mailto:sage [2008/01/29(火) 13:11:53 ]
オブジェクトをByValとByRefで渡したときの違いは何か?
プロパティNameを持った空のクラスClass1を作成し、次のコードを実行してみる。

[結果]
Initialized
abc
def

[考察]
ByValでもオブジェクトのコピーが発生するわけではない。
(barから戻ったときにbarで設定したNameが表示されているので)

--Class1
Public Name as String
Private Sub Class_Initialize()
Debug.Print "Initialized"
Name = "abc"
End Sub

--Module1
Sub foo()
  Dim o As Class1
  Set o = New Class1
  bar o
  Debug.Print o.Name
End Sub

Sub bar(ByVal o As Class1)
  Debug.Print o.Name
  Set o = Nothing
End Sub


561 名前:558 mailto:sage [2008/01/29(火) 13:15:54 ]
続き。
ByValをByRefに変えて実行してみる。

[結果]
Initialized
abc
(ここで実行時エラーが発生する)

[考察]
実行時エラーが発生した行は、barから戻ってo.Nameを参照する行。
このことは、bar内でオブジェクトが破棄された、すなわちByRefは参照カウントを増やしていない
ことを意味する。

>>560の結果とあわせると、結論は、
オブジェクトをByRefで渡すと、それ自身が渡され、参照カウントも増えない。
オブジェクトをByValで渡すと、オブジェクトがコピーされるのではなく、参照カウントが増えるだけ。

562 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 13:16:06 ]
>ByValでもオブジェクトのコピーが発生するわけではない。
これはみんな常識として知ってるだろうね。
もちろん考察には感謝する。

563 名前:558 mailto:sage [2008/01/29(火) 13:19:10 ]
>>562のコードの訂正

Sub bar(ByVal o As Class1)
  Debug.Print o.Name
  o.Name = "def"
  Set o = Nothing
End Sub


564 名前:558 mailto:sage [2008/01/29(火) 13:26:55 ]
さて、それでは実際にオブジェクトのコピーを関数に渡したいときにはどうすればいいのだろう?
とふと思った。

Class1に次の関数を実装すれば良い。
が、VBAの機能だけで実現する方法があるかもしれない・・・。

Public Function Clone() As Class1
  Set Clone = New Class1
  Clone.Name = Me.Name
End Function

Sub foo()
Dim o As Class1
Set o = New Class1
bar o.Clone
Debug.Print o.Name
End Sub

Sub bar(ByRef o As Class1)
Debug.Print o.Name
o.Name = "def"
Set o = Nothing
End Sub

[一連の書き込み終了]

565 名前:558 mailto:sage [2008/01/29(火) 13:30:33 ]
蛇足。

オブジェクトをByValで渡す場合は、前述のようにリファレンスカウントが増えるだけであり、
仮引数のconst性(不変性)を保障するものではまったくない。

その意味で、>>516のポリシーは間違っている。

566 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 13:42:59 ]
しかし試しもしないで遅いとか気持ち悪いとか書くやつも相当だよな。
速度の計測なんてすぐできることだろうに。

567 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 13:49:29 ]
>>565
組み込みオブジェクト(というのか?)だと、ByRefで渡したときは自作クラスのインスタンスとは
ちょっと違う挙動をする。

Sub foo()
Dim r As Range
Set r = Range("A1")
bar r
Debug.Print r.Address
End Sub

Sub bar(ByRef r As Range)
Set r = Range("A2")
End Sub

ByValだと$A$1と表示され、ByRefだと$A$2と表示される。
つまり、ByValは「参照のコピー」が渡ってると言える。(ここ、怪しい表現だが)
そういう意味では>>516は正しい。

あーややこしい。

568 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 13:51:25 ]
いいかげんに許してやりなよ。
勘違いは誰でもあるし、反省してると思うよ。

569 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 13:53:00 ]
あー、それが「参照の参照」という奴なのか・・・



570 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 14:00:29 ]
>>555のリンク先ちらっと見たけど、とてもじゃないが読む気になれん

571 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 14:06:08 ]
禿げ胴

572 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 14:18:49 ]
なんだか混乱してきた。
ただ、byrefの方がbyvalより速いというのが事実だということは確かだよな。

573 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 14:23:25 ]
誰かガンダムで表現してくれ

574 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 14:49:38 ]
オブジェクト型はアドレス渡されるだけで
基本はLong型と同じ
byvalでも渡されるのが参照情報だからbyrefみたいに
感じちゃうってこと

575 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 15:02:19 ]
>>567
それbarの中で新しいRangeオブジェクトを作り出してるから、根本的に565が書いたコードと違う

576 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 15:07:53 ]
>>568
反省してるかねぇ。
すっとぼけてるけど、なんとかByValが遅いのは認めたらしい。
ただお行儀がどうのこうのとまだ言ってるよ。
別に参照渡しは行儀悪くねーだろ?

577 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 16:25:15 ]
>>576
そもそも、VBAのデフォルトがbyrefなんだから、神経質ではない普通の人が
function foo(r as range)
と書くと、それはByRefになる。

これがお行儀が悪いということは、
function foo(byval r as range)
と書くのが「お行儀が良い」ということになる。

こんな書き方がデフォルトの奴は診たこと無いぞ。

578 名前:デフォルトの名無しさん [2008/01/29(火) 16:54:08 ]
右上の×(閉じるボタン)を無効にできますか?


579 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 17:09:17 ]
ところで、516のいう「自分で定義したサイズが大きな型」というのが
Typeで定義した型のことなら、それに関しては同意と言おうと思ったら、
そもそもTypeのユーザ定義型は、値渡しできなかった。



580 名前:550 mailto:sage [2008/01/29(火) 17:26:39 ]
>5回のループじゃなくて25回くらいならほぼ同じになった。もっと回したらやっと逆転した。
仕事から帰って再度試したら、もっと回しても逆転まはしてなかった。スマン
測定誤差だったみたいだな。
誰かが書いてたと思うが、結局ByValが速くなるケースってなさそうだな。

581 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 17:43:20 ]
ChangeイベントやSelectio_ChangeイベントがByVal Target As Rangeとなってるのは何故?
エロイ人教えて






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<253KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef