Excel VBA質問スレ Pa ..
[2ch|▼Menu]
421:デフォルトの名無しさん
08/01/19 17:14:35
OS XP、Excel2003

普段は、VBエディタから 挿入 → 標準モジュール で
Module** といったファイルを作成してコードを書いています。

このModule** というファイルを自分の好きな名前にするのにはどうしたら良いのでしょうか?

422:デフォルトの名無しさん
08/01/19 17:25:27
右クリックの名前を変更かF2でできたと思う。

423:421
08/01/19 19:16:55
>>422
ご解答ありがとう御座います。
しかし、右クリックしても「名前を変更」が見つかりません。
また、F2ではオブジェクトブラウザという表示になるのですが
名前を変更する方法がわかりません。

分かる方みえましたらお願いします。

424:デフォルトの名無しさん
08/01/19 19:22:37
>>423
プロパティウィンドウ→オブジェクト名を変える

425:デフォルトの名無しさん
08/01/19 19:23:18
>>423
プロパティウィンドウの、(オブジェクト名)を変更すると変わる。


426:416
08/01/19 21:26:44
>>419 ありがとうございます。グローバル変数にしたら解決しました。

また基本的な質問ですみませんが
マクロを起動した瞬間にリストboxに
候補を表示させようとしました

Private Sub UserForm1_initialize()
Set com1_r = Range("A1:A5")
With UserForm1.ListBox2
.ColumnCount = 1
.RowSource = com1_r.Address
End With
End Sub

のように書いても表示されません。
他のPrivate Sub TextBox1_Change()等に
書いた時は表示されるのですが
一体何が誤っているか御指摘頂けませんでしょうか?

427:421
08/01/19 21:29:38
>>424
>>425
教えて頂いた方法で出来ました。
大変ありがとう御座いました。お二人に幸あれ。

428:デフォルトの名無しさん
08/01/19 21:56:53
>>426
そのコードをそのままこちらで実行してみたけど、問題なく動いたよ。
何か別の場所でミスしてるんでは?

例えば、
値を表示させたいリストボックスのオブジェクト名が ListBox2 ではなく ListBox1 だった、とか
代入元のセル A1:A5 の値がマクロ起動時には空白だった、とか。

今一度、確認すべし。

429:質問
08/01/19 22:40:54
Visual Basic Editerの画面で何かの拍子に下記のように
操作パネルが統合されなくなってしまいました。
どうすれば元通りにできるでしょうか?よろしくお願いします!

URLリンク(members.at.infoseek.co.jp)

430:デフォルトの名無しさん
08/01/19 23:08:09
>>428 Private Sub UserForm1_initialize()
だとgeneralになっていたので
Private Sub UserForm_initialize()
に直すとUserFormになって動きました。
作ってるのはUserForm1なのに不思議ですね。
ともかく有難うございました。

431:デフォルトの名無しさん
08/01/19 23:51:21
>>430
画面のコントロール以外(フォーム、クラス等)のイベントプロシージャ名は、
オブジェクト名に影響されないハズなんだけどね。何でだろ?

でも、言われてみれば違和感あるよな。今気づいたw


432:429
08/01/19 23:52:15
自己解決しました。
プロジェクトエクスプローラで「ドッキング可能」にしたら直りました。
下記にも載ってました(^^)
URLリンク(www2.moug.net)

433:デフォルトの名無しさん
08/01/19 23:52:47
>>429
メニューの、ツール ⇒ オプション ⇒ [ドッキング] タブ を確認してみて。


434:デフォルトの名無しさん
08/01/20 00:16:46
>>400
47個あるシートから1つのdataと言う名前のシートに集計したい場合は多分これです。

Sub test()
 Dim ws As Worksheet
 Dim r As Range
 Dim rr As Range

 With Worksheets("data")
      Set rr = .Range("A1")
      For Each ws In Worksheets
          If ws.Name <> .Name Then
             Set r = ws.Range("A1").CurrentRegion
             rr.Resize(r.Rows.Count, r.Columns.Count).Value = r.Value
             Set rr = rr.Offset(r.Rows.Count)
          End If
      Next
 End With
End Sub



435:デフォルトの名無しさん
08/01/20 00:28:12
>>427
祈われるまでもなく幸ねぇよw

>>400
もうちょい詳しく書かないと失礼だぞぅ

436:デフォルトの名無しさん
08/01/20 00:30:46
range変数で格納できる範囲はRange(Cells(1, 1), Cells(5, 4))
のような一枚のワークシート上の範囲だけでなのでしょうか?
1枚目のRange(Cells(1, 1), Cells(5, 4))と2枚目のなんたらのように
別のsheetにわたった範囲の格納などしたい場合はどうすればいいのでしょう

437:デフォルトの名無しさん
08/01/20 00:57:59
>>436
それは無理。 クラスの概念を知らないと分からないかもしれないけど。

別々の変数に持たせるしかないと思う。もちろん、配列やコレクションは使えるはず。


438:デフォルトの名無しさん
08/01/20 20:46:37
Excelの分析ツールを使ってランダムにサンプルを取り出して計算するシート作ったのですが
Application.ScreenUpdating = False
て書いてもサンプル取り出すたびに再計算画面が出てしまいます
画面更新しないようにするにはどうしたらいいですか?

Sub MonteSample()
Dim myMonte As Integer
Dim i As Integer
Dim myMsg As String, myTitle As String
Dim myFun As Range
Dim myAv As Long, myStd As Long, myMax As Long, myMin As Long
Dim n As Long
Dim mysouce As Range
Dim mydat As Range
Dim mydats As Range
myMsg = "計算回数を入力してください"
myTitle = "モンテカルロ・シュミレーション"
myMonte = Application.InputBox(prompt:=myMsg, Title:=myTitle, Default:=30, Type:=1)
If Range("A12") = "" Then
MsgBox "A12のセルから損益のデータを入力してください", vbOKOnly + vbExclamation
End
End If

Range("D12:D1011").Select
Selection.ClearContents
Range("K32:K100").Select
Selection.ClearContents
Range("i32:i33000").Select
Selection.ClearContents

Application.ScreenUpdating = False

439:デフォルトの名無しさん
08/01/20 20:48:04
For i = 1 To myMonte
Range("A12").Activate
Set mydat = ActiveCell.CurrentRegion
Set mydats = mydat.Offset(1, 0).Resize(mydat.Rows.Count - 1, _
mydat.Columns.Count)
Application.Run "ATPVBAEN.XLA!Sample", mydats, _
ActiveSheet.Range("D12:D1011"), "R", 1000, False
Range("I65536").End(xlUp).Offset(1).Select
ActiveCell.Value = Range("E1011")
Range("D12:D1011").Select
Selection.ClearContents
Next i
Range("N4").Value = myMonte
Range("I31").Activate
Set myFun = ActiveCell.CurrentRegion
myFun.Offset(1, 0).Resize(myFun.Rows.Count - 1, _
myFun.Columns.Count).Select
myAv = Application.WorksheetFunction.Average(myFun)
Range("N5").Value = myAv
myStd = Application.WorksheetFunction.StDev(myFun)
Range("N6").Value = myStd
myMin = Application.WorksheetFunction.Min(myFun)
Range("N7").Value = myMin
myMax = Application.WorksheetFunction.Max(myFun)
Range("N8").Value = myMax
Range("K32").Value = myMin
Range("K33").Select

440:デフォルトの名無しさん
08/01/20 20:49:08
For i = 1 To 49
n = ActiveCell.Offset(-1).Value
ActiveCell.Formula = Int((Abs(myMin) + myMax) / 49) + n
ActiveCell.Offset(1).Select
Next i
Range("L32:L81").Select
Selection.FormulaArray = Application.WorksheetFunction.Frequency(myFun, Range("K32:K81"))

Set mysouce = Range("L32:L81")

ActiveSheet.ChartObjects(1).Activate
ActiveChart.SetSourceData Source:=mysouce, PlotBy:=xlColumns

Application.ScreenUpdating = True

End Sub


441:デフォルトの名無しさん
08/01/20 21:03:23

Application.ScreenUpdating = False
Application.ScreenUpdating = True


Application.EnableCalculation = False
Application.EnableCalculation = True


442:デフォルトの名無しさん
08/01/20 21:22:32
>>441
再計算しない場合はそんなのあるのか、ありがとう。
でも、変えてみたけど実行時エラーでてだめだった、
ワークシートで再計算してるから使えないのか
ワークシートの再計算はそのままで画面の更新だけ止めるのはできないのかな


443:441
08/01/20 22:05:30
折れには、試す気もないのでわからない。
続けての回答を待っているといけないから、折れには以後書くことはないと伝えておくよ。

あと、折れが使うのは
Application.EnableEvents = False (と True)
Application.Visible = False (と True)


444:デフォルトの名無しさん
08/01/20 22:17:22
>>443
いろいろありがと
新しいこと少し覚えられてよかったw
まあ、うまくいかなかったけど趣味で使ってるだけだから
そのうちできるようになると思うのでゆっくりやります

445:デフォルトの名無しさん
08/01/20 23:58:30
>>442
全くためしてないんだが

Application.ScreenUpdating = 画面の更新をするか
Application.EnableCalculation = 再計算してるか

を考えれば幸せになるんじゃね?

俺的には全部コードでやっちゃうがw

446:441
08/01/21 01:01:55
>>442での「実行時エラー」ってのが、気になった・・・
application.run関係ぐらいしか実行時エラーが出うる箇所はないように見えた。

もしかしたらだけど、ここが参考になるかも
 URLリンク(www.geocities.jp)

おやすみ


447:デフォルトの名無しさん
08/01/21 01:59:57
>>445
>>446
ありがとうございます。
441さんの指摘のようにapplication.runが原因みたいです
Excelの分析ツール使うと画面更新されてしまうみたいです
ワークシート上だけで乱数関数使って同じようなコードで実行したら、
画面は更新されないでうまくいきました。
鋭い指摘ありがとう!


448:デフォルトの名無しさん
08/01/21 15:40:17
例えば、C3からK11まで範囲指定するのに、
rangeを使わず、offsetを使って指定することは可能でしょうか。

やりたいことをイメージ化すると以下のようなのですが・・・

Sub hoge()
Range("A1").Select
Range(ActiveCell.Offset(2, 2).Select, ActiveCell.Offset(10, 10).Select).Select
End Sub

449:デフォルトの名無しさん
08/01/21 15:58:59
あのさ、
いちいちこのスレで聞くよりもさ、
自分でググるなり本を買うなりして調べた方が圧倒的に早いと思うんだけど。

450:デフォルトの名無しさん
08/01/21 16:09:36
range("A1").select
range(selection.offset(2, 2), selection.offset(10, 10)).select
--
dim r as range
set r = range("A1")
debug.print range(r.offset(2, 2), r.offset(10, 10)).address
range(r.offset(2, 2), r.offset(10, 10)).value = 12345


451:デフォルトの名無しさん
08/01/21 16:10:15
>>448
つか、目的がよくわかんねーよ。 あと、その例文、.Offset に .Select付いてたらエラーになるぞ。

そもそも、Offset って、基本的にRangeのプロパティなんだが。Rangeを使わずにどうしろと?


452:デフォルトの名無しさん
08/01/21 16:57:48
If 気に入らない or わからない Then
  スルーしろ
End If

453:デフォルトの名無しさん
08/01/21 17:01:03
意味が分かれば協力する気持ちがあるから訊いてるんだよ。全否定すんな。
それとも、どこが分からないか、こちらが分かりやすく優しく丁寧に質問しないとダメなのかよ?


454:448
08/01/21 17:19:29
すまん!

Sub hoge()
Range("A1").Select
Range(ActiveCell.Offset(2, 2), ActiveCell.Offset(10, 10)).Select
End Sub

selectとったらいけました。
逝ってくる

455:デフォルトの名無しさん
08/01/21 17:56:47
>>453
やりたいことの「イメージ」って書いてるだろ。
これで意図がわからんというのがわからん。

456:デフォルトの名無しさん
08/01/21 20:42:56
>>453はかわいそうな子


457:451
08/01/21 21:10:50
>>455
レスの流れぐらい見ろよ。レスから読み取れる範囲で回答はしてる。
それとも、IDがないと同一人物かどうかも判断できんか?


458:デフォルトの名無しさん
08/01/21 23:47:53
構造体の2次元配列の参照って
Kouzoutai(1,2).Member = 1

という形であってます?
オブジェクトが必要ですとかいうエラーが返ってくるんですが…

459:デフォルトの名無しさん
08/01/21 23:59:26
すごいな。
もう思いついたことをとりあえず質問するスレになってるな。
>>458なんてはなっから自分で調べる気ないもんな。

460:デフォルトの名無しさん
08/01/22 00:30:46
>>458
オブジェクトがないんだよ。
Dim Kouzoutai( 5, 5 ) as HOGE
って形になってるか?

どうせ
Type Kouzoutai
Member as integer
End Type
とかになってんだろ。

「VBA 構造体」でググればびっくりするくらいヒットするじゃないか。

461:デフォルトの名無しさん
08/01/22 07:24:11
OSはWindows XP Home Edition、
Excelは2003の11.8169.8172です。
VBA初心者でここも初めてです。質問させてください。
2種類のグラフをそれぞれ別のシート上のオブジェクトとして作成しました。
(2つ同時ではなく、まず1つ目のグラフを作り、その後別のグラフを作るというやり方です。)
2つ目のグラフを作る際、1つ目のグラフの数値軸で自動的に表示された軸の最大値と最小値を
2つ目のグラフにも反映させたい(同一の値にしたい)のですが、
どのように記述すれば1つ目のグラフの最大値や最小値を呼び出すことができますか?
With ActiveChart.Axes(xlValue)
.MinimumScale = ココと
.MaximumScale = ココです。
End With

ぜひヒントがほしいです、よろしくお願いします。

462:デフォルトの名無しさん
08/01/22 12:59:28
>>461
確認する時間がないのでヒントのみ。 あとはヘルプ見ながら直して。
 Dim s As Worksheet
 Dim c As ChartObject
 Set s = Worksheets.Item("test")   ←"test" って名前のシートが取得できる
 Set c = s.ChartObjects(1)       ←取得したシートの、1つめの図を取得
あとは c.Chart.Axes.Item(xlValue).MinimumScale な感じで対応する値が取得できると思われ。
まとめて書くこともできるが、とりあえず入力補助に反応する書き方にしといた。


463:デフォルトの名無しさん
08/01/22 13:25:13
E6からE26とN6からN26に数字を入力したのですが、このコードよりも簡単な方法はないでしょうか?


Dim c As Long
Dim f As String
Dim v1() As Variant
Dim v2() As Variant
With Excel.Range("E6:E26,N6:N26")
c = .Areas.Item(1).Count
f = "ROW(" & .Worksheet.Range("A1") _
.Resize(c).Address & ")"
v1 = .Application.Evaluate(f)
v1 = .Application.Small(.Cells, v1)
f = "ROW(" & .Worksheet.Range("A" & 1 + c) _
.Resize(.Areas.Item(2).Count).Address & ")"
v2 = .Application.Evaluate(f)
v2 = .Application.Small(.Cells, v2)
.ClearContents
.Areas.Item(1).Value = v1
.Areas.Item(2).Value = v2
End With


464:デフォルトの名無しさん
08/01/22 13:31:48
>>463
日本語でやりたいことを書け

465:デフォルトの名無しさん
08/01/22 13:38:05
>>463 観光客の人数をExcelで作成したのですが、E6からE26とN6からN26
に観光客の人数を入力したのですが、これを小さい順に書き換えるにはどうし
たらいいのですか?


466:デフォルトの名無しさん
08/01/22 13:46:13
つ【並べ替え(S)】


467:デフォルトの名無しさん
08/01/22 18:25:19
「セルが特定の値以外のとき、自分の行を削除」したい。
IFでセル内容を指定してから
Range.deleteでどうやって削除条件にすべきでしょうか。

468:デフォルトの名無しさん
08/01/22 20:22:56
な、何なんだこのスレは・・・

469:デフォルトの名無しさん
08/01/22 22:05:12
このスレは池沼のフリして教えたがりのうざいヲタを釣るスレですが、なにか?

470:デフォルトの名無しさん
08/01/22 22:13:25
ってことはこれは釣れたってことでFA?

471:デフォルトの名無しさん
08/01/22 22:49:21
>>470
お前がなw

472:デフォルトの名無しさん
08/01/22 23:03:33
やたー☆

473:デフォルトの名無しさん
08/01/23 11:53:11
やったー +1

474:デフォルトの名無しさん
08/01/23 18:41:55
ここで良いかどうか分かりませんが・・・

ビデオカードの現在の解像度(できればモニタのインチ数も)によって、
ActiveWindow.Zoomの値を変更するプログラムを考えているのですが、
vbaでビデオカードの現在の解像度を調べるのは不可能でしょうか?

475:デフォルトの名無しさん
08/01/23 21:16:04
>>474

vba api 解像度 でぐぐれば、2番目にあなたの望む回答が

476:デフォルトの名無しさん
08/01/24 08:57:54
良回答認定

477:デフォルトの名無しさん
08/01/24 09:11:24
>>475
ありがとうございます!

下調べはしてたつもりだったのですが、
甘かったです・・・orz

478:デフォルトの名無しさん
08/01/24 10:01:12
恥ずかしながら全く分かりません。
何卒お願い申し上げます。


次の選択肢より正しい記述をすべて選びなさい。

1:java.io.FileReaderはテキストファイルから文字を行単位で読み込むクラスである。
2:new File("bbs.txt")と記述すると、新しいファイルが作成される。
3:ファイルの操作を行う前には、Fileクラスのopenメソッドを必ず使用する。
4:BufferedReaderクラスのreadLineメソッドは、ファイルの終端までを読み込む。
5:FileクラスのisFileメソッドの戻り値がfalseだった場合は、そのファイルが無いか、またはその名がディレクトリである事を示している。


479:デフォルトの名無しさん
08/01/24 10:06:39
>>478です。
申し訳ありません、スレ違いでした。
失礼致しました。

480:デフォルトの名無しさん
08/01/24 10:33:36
アクセスのVBAのスレが見付からないのでここで質問します。
アクセスのVBAで、フォーム1
ユーザ登録画面
ユーザ名[ ]
パスワード[ ]
登録
があり、2つを入力し、登録を押したら登録できるのを教えてください

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

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


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

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

486:485
08/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
08/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:デフォルトの名無しさん
08/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
08/01/24 18:00:49
>>488
どうもありがとうございます!!
突っ込みどころ満載ですか…笑
ご指摘を元に再度勉強してがんばってみます!!

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


491:デフォルトの名無しさん
08/01/25 09:36:51
漁獲量・・・

492:デフォルトの名無しさん
08/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:デフォルトの名無しさん
08/01/26 01:11:11
すみません。色々試行錯誤していたら解決しました。有難うございました

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

495:デフォルトの名無しさん
08/01/26 17:48:24
余りに低レベルなので泣けてきました。

496:デフォルトの名無しさん
08/01/26 17:52:19
OLEコントロールの名称でないの。
Microsoft Forms 2.0 TextboxのPROGID

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

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

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

環境はWinXP SP2+Excel2000です


498:デフォルトの名無しさん
08/01/27 13:57:52
↑根本的に何かを勘違いしてないか?

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

500:デフォルトの名無しさん
08/01/27 18:11:32
ソルバ?
URLリンク(www.joy.hi-ho.ne.jp)

501:デフォルトの名無しさん
08/01/27 23:00:39
Excel2003です。
OnErrorでエラーメッセージの出力を指定しても、

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

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


502:デフォルトの名無しさん
08/01/27 23:16:08
デバッグトレースシテクダサーイ

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


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

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


506:デフォルトの名無しさん
08/01/28 01:16:04
>>504
金払って許してもらおうぜ

507:デフォルトの名無しさん
08/01/28 10:02:19
うんこ出た
超きもちいい


508:501
08/01/28 12:59:32
マクロの最初に

On Error Msgbox
On Error exit Sub

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

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

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

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


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

512:デフォルトの名無しさん
08/01/28 17:52:07
なんだ、下はEnd Subになってるじゃん

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

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

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


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

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

518:デフォルトの名無しさん
08/01/28 20:42:00
>>515
やってみりゃわかるけど、byrefの方が速いよ

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

520:デフォルトの名無しさん
08/01/28 20:51:52
ポインタのポインタかよ

521:デフォルトの名無しさん
08/01/28 20:53:43
&*p ← キモチワルイ

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

523:デフォルトの名無しさん
08/01/28 21:27:27
測定誤差

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

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

526:デフォルトの名無しさん
08/01/28 22:38:42
エロい方timeGetTimeで測定オナがいしますorz

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

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

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

530:デフォルトの名無しさん
08/01/28 22:57:51
えええ?

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

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


533:デフォルトの名無しさん
08/01/28 23:07:39
なんか思いっきり勘違いしてる人がいない?

534:デフォルトの名無しさん
08/01/28 23:08:44
>>533
ちゃんとポイントして指摘しろ

535:デフォルトの名無しさん
08/01/28 23:10:19
いや彼にはそのままでいて欲しいからやめとく

536:デフォルトの名無しさん
08/01/28 23:25:40
なら最初から黙っとけよ

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

538:デフォルトの名無しさん
08/01/28 23:32:10
ここVBAのスレだよなぁ?

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

540:デフォルトの名無しさん
08/01/28 23:45:18
>>539
試せばわかる

541:デフォルトの名無しさん
08/01/28 23:47:58
ところで514とか516とか529は試したんだろうか?

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

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


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

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

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

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

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

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

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


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

552:デフォルトの名無しさん
08/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:デフォルトの名無しさん
08/01/29 08:27:03
モタモタしてるうちに>>551が間に入ったな。

554:デフォルトの名無しさん
08/01/29 10:10:38
Mougからきました。
勉強になりました。

555:デフォルトの名無しさん
08/01/29 10:51:23
URLリンク(www2.moug.net)
私もここからきますた。
ビヒネスソフト板以外にExcelのスレがあるとは知らんかった。

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

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

558:デフォルトの名無しさん
08/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
08/01/29 13:07:28
気持ち悪いコードって俺の?
だったらすまんね。

560:558
08/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
08/01/29 13:15:54
続き。
ByValをByRefに変えて実行してみる。

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

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

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

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

563:558
08/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
08/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
08/01/29 13:30:33
蛇足。

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

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

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

567:デフォルトの名無しさん
08/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:デフォルトの名無しさん
08/01/29 13:51:25
いいかげんに許してやりなよ。
勘違いは誰でもあるし、反省してると思うよ。

569:デフォルトの名無しさん
08/01/29 13:53:00
あー、それが「参照の参照」という奴なのか・・・

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

571:デフォルトの名無しさん
08/01/29 14:06:08
禿げ胴

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

573:デフォルトの名無しさん
08/01/29 14:23:25
誰かガンダムで表現してくれ

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

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

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

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

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

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

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


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

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

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

582:デフォルトの名無しさん
08/01/29 17:57:41
差を比べるならこうする
わかるのは差は大きいが全体でみると微々たる差ということ

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:Q")
t(0) = timeGetTime
For i = 1 To rng.Count
TEST1 c
Next
t(1) = timeGetTime
For i = 1 To rng.Count
TEST2 c
Next
t(2) = timeGetTime
Debug.Print "TEST1", t(1) - t(0); "ミリ秒"
Debug.Print "TEST2", t(2) - t(1); "ミリ秒"
End Sub

Private Sub TEST1(ByRef c As Range)
End Sub

Private Sub TEST2(ByVal c As Range)
End Sub



583:510
08/01/29 18:00:36
みなさん、大変参考になりました。
どうやら参照渡しで問題ないということがわかり一安心です。
ありがとうございました。

584:550
08/01/29 18:15:46
>>582
俺はcへのアクセス速度も調べたかったんだよ。
>>529が気になったものでね。

>>583
よかったな、まぁがんがれ

585:デフォルトの名無しさん
08/01/29 19:40:38
この流れを見て「Byrefなら速いんだ!」となんでもかんでもByrefの迷惑コーダーが量産されそうな

586:デフォルトの名無しさん
08/01/29 19:41:25
デフォルトbyrefなんでそ?

587:デフォルトの名無しさん
08/01/29 19:46:43
>>585
デフォルトがそうだし、仮に全部ByRef にしたトコで悪影響があるんだろうか?
要するに、関数にオブジェクト変数を渡せば、ByValにしたとこで内容の保護はできんわけだし。


588:デフォルトの名無しさん
08/01/29 20:56:04
>>585
それは言えるかも知らんね。ByValが速いケースもあるんだけどな。
オブジェクト型はないかも知らんが、他のケースでは確実にある。

589:デフォルトの名無しさん
08/01/29 21:32:15
>>588
だから、そのケースを示せっての。議論のネタにもならんわ。 自分がそう信じたいだけか?


590:デフォルトの名無しさん
08/01/29 21:37:50
>>589
おめー死ねよ。
自分で探すことも出来んのか?

591:デフォルトの名無しさん
08/01/29 21:54:54
おまえは間違ってる(でも正解を示さない)
↑ググってみて一番上ね

592:デフォルト知らず
08/01/29 21:59:20
折れ、今まで、全てにおいてByRefにせず、ByValできている。反省w
戻り値を親に返す必要がないから、ByValを当然に使うと考えていた。

戻り値を親に戻す必要があればByRefと、ただ単にプログラムテクニックぐらい。
で、スピードは全く気にしていなかった。

ベンチマークでなく、実用・実践のレベルでのものでも、書き換えた方が早いのだろうか? ex 与件を渡すinteger型変数5つぐらい


593:デフォルトの名無しさん
08/01/29 22:14:57
いいから>>589は死ね。
おれはここで散々>>510のケースはByRefが速いって書いてきたからな。
勘違いするなよ。

594:デフォルトの名無しさん
08/01/29 23:53:02
すみません
Cells(hoge, fuga).Value
で値を取り出したときに
元のセルが3だったとすると
値がそのまま3である場合と
3.0になっている場合があるようなんです
常に3であるように取り出すにはどうするのがよいでしょうか?

595:デフォルトの名無しさん
08/01/30 03:58:58
>>593
お前が死ね。
二度と来るな。
迷惑だ。

596:デフォルトの名無しさん
08/01/30 05:05:50
>>555
モーグは、大村なんとかが嫌いだったので見てなかったんだが、久しぶりに見に行ったら
井川はるきという気持ち悪い奴がのさばってた。

ぐぐったら、こいつ何冊も本出してるな。
掲示板で初心者相手に回答もしてるみたいだし、ほんときもちわりー

597:デフォルトの名無しさん
08/01/30 07:37:28
オラもモーグから来ますた。
ByRefとByValの話はもう終わり?
何かあるのかと思ったら、既出ネタの応酬とグダグダの展開に正直がっかりです。

598:デフォルトの名無しさん
08/01/30 09:35:53
もともと既出ネタなのに、何を期待してたんだ?

599:デフォルトの名無しさん
08/01/30 11:02:26
>>596
お前よりは役にたってるよ。
今回の引数の渡し方については、嘘をどうどうと書いたので叩かれてもしょうがないけどな。

600:デフォルトの名無しさん
08/01/30 11:13:05
しかし彼の本にオブジェクト型はByValで渡すべしなんて書かれてたりしたら、本を買った人がかわいそうだな。

601:デフォルトの名無しさん
08/01/30 11:19:17
>>594
そんなのありえないだろ?
元のセルが3.0という文字列なら別だが、もともと数値の3なら3だ。
どこかのセルにその値を代入すれば、表示形式によっては3だったり3.0だったりすることはあるがね。

602:デフォルトの名無しさん
08/01/30 12:31:31
>>599
役にたってるかなんかどうでもいい。

気持ち悪いかどうかって話だ。


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

4790日前に更新/253 KB
担当:undef