トップページtech
1002コメント383KB

Excel VBA 質問スレ Part39 [転載禁止]©5ch.io

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2015/11/27(金) 20:36:45.35ID:9HV+ag/s
ExcelのVBAに関する質問スレです

                   ___
       ___      /____ヽ      ____
      /____\    | |´・ω・`| |    /___ヽ
      .l |´・ω・`|  ニX二 . ̄ ̄ ̄  二X二  |´・ω・`| l 俺たちに任せろ
      !、 ̄ ̄ ̄  ヽ   |       |    /    ̄ ̄ ̄/
       ヽ_/ヽ、  ヽ__)  \__/\_/.   /_/  ノヽ_/
             ̄                ̄ ̄

このスレはコード書き込みOKです。
作成依頼もOKですが、作成依頼限定ではありません。

コードが嫌な人・作成依頼が嫌な人は別スレ建ててください。

※前スレ
Excel VBA 質問スレ Part38 [転載禁止]2ch.net
http://peace.2ch.net/test/read.cgi/tech/1441619979/
0052デフォルトの名無しさん2015/12/08(火) 19:55:43.49ID:ZPfyD2ax
誰か>>48頼む!
=if(a3>a2,3,-3)を入力しても無理だった・・・
0053デフォルトの名無しさん2015/12/08(火) 19:57:18.42ID:J4OFLa1h
>>51
同時には実行されないから、関数よりもマクロが先に実行される仕組みならマクロが先に代入する。

>>52
VBAの話題ではない。
0054デフォルトの名無しさん2015/12/08(火) 20:50:48.64ID:4cJ0X+3R
>>52
無理って何だよ?それでいけるだろ
0055デフォルトの名無しさん2015/12/08(火) 21:36:53.02ID:KvNJeD9m
>>52
セルの書式が文字列とかじゃね
0056デフォルトの名無しさん2015/12/08(火) 21:49:08.87ID:46EuwWyR
>>51
計算方法が自動なら
> A1に○○代入(数値)
で再計算が行なわれる
以下
> A20に○○代入(数値)
まで、20回計算される
なので
> この場合にB1セルの計算が終わる前にVBAが追い越して数値を代入することってありえるの?
なんてことはない
20回も計算するのは時間がかかってしょうがないと言う時は、最初に Application.Calculation = xlCalculationManual とかして計算しない様にしておいて、A20 に代入したあとで、Application.Calculate とか実行しすると計算は1回ですむ
0057デフォルトの名無しさん2015/12/09(水) 01:33:16.84ID:bb4JBp1r
>>53>>56
なるほどなー

要するに、VBAでセルに数値が代入される→数値が変わった時点でセル内の再計算→またVBAに戻る

って感じか。なるほどなるほど。ありがと
0058デフォルトの名無しさん2015/12/09(水) 01:56:13.57ID:A8KFlPn0
全てセミコロンに変えたら解決できました
=if(c3>c2;3;-3)

どうもありがとう
0059デフォルトの名無しさん2015/12/09(水) 02:02:30.52ID:ZB9BGZbY
なりすまし
0060デフォルトの名無しさん2015/12/09(水) 11:36:59.80ID:NOtadkaS
エクセルにcsvファイルのデータを貼り付けて一部の列にvlookupの数式を上書きしたいんですけど
どうすればよいですか?
マクロにしたいのは数式の上書き部分だけです
0061デフォルトの名無しさん2015/12/09(水) 12:25:31.08ID:ZB9BGZbY
>>60
例えばC列に数式を入れたいときは

Range("C1").Formula = "=VLOOKUP(B1,A:A,1)"

みたいに数式を文字列にしてセルのFormulaに入れればいい
0062デフォルトの名無しさん2015/12/09(水) 16:22:59.08ID:NOtadkaS
>>61
ありがとうございます。
0063デフォルトの名無しさん2015/12/09(水) 16:59:02.21ID:bb4JBp1r
学生でVBAとSQL使って競馬のソフト作ったりして遊んでるけど、就活の時にそういうのアピールしてもいいかな
0064デフォルトの名無しさん2015/12/09(水) 17:09:37.89ID:h+7RpR46
>>63
マジレスすると、ギャンブルするような学生はいらんってことになるな
0065デフォルトの名無しさん2015/12/09(水) 17:21:13.51ID:bb4JBp1r
>>64
やっぱり印象悪いかな
データ集めて統計使って指数出したりするの好きなんだよな
0066デフォルトの名無しさん2015/12/09(水) 17:57:02.43ID:h+7RpR46
>>65
さらにマジレスすると、独創的なアルゴリズムを使った予想をしているならそのアルゴリズム
その、実装がむずかしいとされているものを既存のアルゴリズムを用いて実装したり(遺伝的
アルゴリズムでNSPを解決するなど)があるなら、アピールポイントになると思うよ
0067デフォルトの名無しさん2015/12/09(水) 22:32:23.05ID:ulePTNdz
素人にはプログラムなんてよく分からないからね
自分も入社時に現場叩き上げの人直々に面接されたが、WindowsのGUIアプリをフロッピーで持っていった所、
結局何が書いてあるのか分からなかったのか見てもらえなかったし
Unixの知識についてはあれこれ聞かれたが

IT業界以外ならVBAを使いこなせます、アプリ作ったことありますってだけで十分アピールポイントになると思うよ
VBAって何?SQLって何?ってことになる可能性があるからそこら辺はしっかり予習した方がいいと思うけど
0068デフォルトの名無しさん2015/12/10(木) 04:22:52.80ID:LKPBxMee
どういうところに修飾したいかもわからんのにまともなレスが返せるわけもなく
人生相談ならよそでやってくれ
0069デフォルトの名無しさん2015/12/10(木) 05:00:47.29ID:00S+xOQk
面接で見られてるのは技術じゃなくて人柄なんだってば

技術的なことなら筆記試験や小論文で判断できる
重要なのは「何をやったか」という内容じゃなくて、それをどう説明するかっていう、プレゼンまでは行かなくても話し方が見られてる
0070デフォルトの名無しさん2015/12/10(木) 07:11:06.38ID:DygANkW8
>>69
できる新人なんてほんと稀
できますって入ってきた奴が作ったものはバグだらけ
未経験のほうがよっぽどバグが少ない
まあこんなこともあるから経験の有無なんてほとんど誤差
0071デフォルトの名無しさん2015/12/10(木) 08:00:18.24ID:+sdtvmJJ
面接官も同じような面接質問ばっかしてるだろうから
面白がってはくれるだろうね。

採用につながるかは分からんが。
0072デフォルトの名無しさん2015/12/10(木) 13:03:32.27ID:uuSHmo9z
VBAにおけるIE11の制御において、普段は大丈夫なのに、
画面ロック中(スリープ後など)だけ、なぜかSELECT要素が参照できなくなります
他のINPUT要素などは問題なく参照できます
IE8からIE11に変えてから起きるようになった気がします
できるだけIE11で行いたいのですが、何が原因でこのようなことが起きるのでしょうか
0073デフォルトの名無しさん2015/12/10(木) 16:23:47.48ID:vMPjIzZK
http://xxx.com/contents.html#R1N1
セルにコピペした、上記のようなラベルを含むハイパーリンクを正常に機能させたいのですが、
「#」が「-」に置き換わっているような挙動をして意図したページが開けません。
ハイパーリンクの編集で確認しても上記の通り入力されています。改善方法はあるでしょうか?
0074デフォルトの名無しさん2015/12/10(木) 16:26:05.28ID:kl2q0NOf
>>73
このリンクはクリックするなよ
0075732015/12/10(木) 16:30:40.32ID:vMPjIzZK
書き込み後ためしに自分もクリッコしたんですが、変なサイトに飛びました・・不適切な例を使って申し訳ないです
0076デフォルトの名無しさん2015/12/10(木) 20:33:09.52ID:GTbd/bMS
VBAでCreateObject("Scripting.Dictionary")とすると
連想配列が使えることを知ったのだけど
動的配列(要素を放り込むと勝手に伸びていく配列)はないですかね
普通の配列は、要素数を決めてDimなりReDimなりしてからでないと
使えなくて不便で…
0077デフォルトの名無しさん2015/12/10(木) 20:37:45.04ID:m24vGLCh
>>76
ないと思うけどDictinaryではダメなポイントは何?
0078デフォルトの名無しさん2015/12/10(木) 20:39:24.26ID:CRNEQuUV
>>76
標準で使えるのはCollectionかな。

動的配列はByRefで渡した先で要素数を変更出来るので、
これを利用して自分で配列伸ばす関数作る事も出来るけど。
0079デフォルトの名無しさん2015/12/10(木) 21:02:59.81ID:GTbd/bMS
>>77
Dictionaryは要素の格納順が保証されないというのがネックです
例を挙げると、印刷すべきシート名を条件判断で選別しながら配列に放り込んでいき
最後にFor Eachで格納順に印刷する、というような処理があります

>>78
Collectionを調べてみます
ありがとうございます
0080デフォルトの名無しさん2015/12/10(木) 21:11:34.59ID:CRNEQuUV
格納順を保証したいならキーを1〜nにすればいいのに。
0081デフォルトの名無しさん2015/12/10(木) 21:50:20.75ID:LgWPhvQB
>>79
なんだ、その程度の配列サイズと頻度か。
だったら (配列, 追加する要素) を引数にとって、要素がひとつだけ大きい配列を返す関数を作ればいい。
効率なんか考えなくてOK。
0082デフォルトの名無しさん2015/12/10(木) 22:14:34.44ID:Ek2aQ7ct
配列myArray(1 to 10, 1 to 10)で
myArray(5, i), myArray(5, i+1), myArray(5, i+2) の最大値を求めるのはworksheetfunction.Maxを使えばいいですが、
最大値の i を求めるスマートな方法ってありますか?

例えば、myArray(5, 2), myArray(5, 3), myArray(5, 4)の最大値となる(5,?)を求めたい時、

i=2
dblMax=WorksheetFunction.Max(myArray(5, i), myArray(5, i+1), myArray(5, i+2))

for j=i to i+2
if dblMax=myArray(5, i) then
debug.print i '最大値をとるときのi
EndIf
Next j

って書くのもなんか泥臭いというか素人っぽいというか・・・
0083デフォルトの名無しさん2015/12/10(木) 22:20:17.87ID:CRNEQuUV
Sub test()
k = 1
For i = 1 To 10
If myArray(5, k) < myArray(5, i) Then k = i
Next
Debug.Print k
End Sub

よく分からんがこういう事か?
0084デフォルトの名無しさん2015/12/10(木) 22:39:25.36ID:Ek2aQ7ct
>>83
早速どうも。コードありがとうございます。

myArray(1,1) = 3
myArray(1,2) = 5
myArray(1,3) = 4

のとき、For文でしらみつぶしに調べることなく、
最大値となる(1,2)などを返す方法はないかなと思ったのです。
0085デフォルトの名無しさん2015/12/10(木) 22:48:15.01ID:CRNEQuUV
>>84
既にソートされているとか、そういう前提条件がない場合は虱潰し以外の方法はない。
素人くさいコードを書きたくないなら、VBAを見よう見まねで触る前に電子工学を学ぶ事をお勧めする。
0086デフォルトの名無しさん2015/12/10(木) 23:06:09.69ID:Ek2aQ7ct
>>85
端的な回答ありがとうございました。
前提条件はないので、シラミ潰しします。
素人なので素人臭くないスマートなコードに憧れます。
この発想が素人臭いのかもしれませんがw
0087デフォルトの名無しさん2015/12/11(金) 01:01:09.23ID:Gc5rivvs
WorksheetFunction.Matchを使えばいいんやよ
0088デフォルトの名無しさん2015/12/11(金) 12:01:23.27ID:e4IICcKi
>>76
http://officetanaka.net/excel/vba/tips/tips98.htm
0089デフォルトの名無しさん2015/12/11(金) 12:29:13.10ID:Wogf6bzX
>>88
MSDN見てみたが、これ使えるのかな?

ArrayList.Sort (IComparer)
指定した比較演算子を使用して、ArrayList 全体内の要素を並べ替えます。
0090デフォルトの名無しさん2015/12/11(金) 13:44:45.39ID:mI4o0uWv
配列要素の並び替えできたら便利だよなー。
帰って調べてみよ。
0091デフォルトの名無しさん2015/12/11(金) 14:19:39.54ID:UJeMV01i
>>87
>>82です。Match引数を配列とすることもできるんですね。
でもあるサイトで配列を引数とするとちょっと遅いみたいな記述がありちょっと心配ですが。

>>88
横からですが便利そうですね。
0092デフォルトの名無しさん2015/12/11(金) 22:44:49.09ID:fIX9Jv1V
質問です

式は適当です

条件1の時
if cells(1,1) = cells(2,1) then

条件2の時
if cells(1,1) = cells(2,1) and cells(1,2) = cells(2,2) then

条件3の時
if cells(1,1) = cells(2,1) and cells(1,2) = cells(2,2) and cells(1,3) = cells(2,3) then

条件nの時
if cells(1,1) = cells(2,1) and cells(1,2) = cells(2,2) and ... and cells(1,n) = cells(2,n) then

てな具合に、判断する項目が増減する時、
スマートな条件式を記述する方法ってありませんか?
0093デフォルトの名無しさん2015/12/11(金) 23:03:48.59ID:Kp08ZeAC
>>92
もっと具体的でないとスマートな(効率的な)式が分からないけど、
例にしているものをコードにするなら

Function Test() as Boolean
For Each x In Range(Cells(1, 1), Cells(1, Columns.Count).End(xlToLeft))
If x <> x.Offset(1, 0) Then Exit Function
Next

Test = True
End Function



Function Test(cond As Long) As Boolean
For i = 1 To cond
If Cells(1, i) <> Cells(2, i) Then Exit Function
Next
Test = True
End Function

かな。
0094デフォルトの名無しさん2015/12/12(土) 01:48:04.85ID:FuRVZgYl
素人でIE操作を試行錯誤しているのですが、どなたかアドバイスいただけますでしょうか。

1.表示されたページのAタグの中からキーワードを抽出してクリック
2.ページが表示されたら、そのままプルダウンなどを選択してクリック

と連続して操作させたいのですが、Aタグから抽出してクリックはできるものの、
その後デバッグになってしまい以降の処理が連続で行えません。

Set objA = objIE.Document.getElementsByTagName(
0095デフォルトの名無しさん2015/12/12(土) 01:49:15.80ID:FuRVZgYl
Set objA = objIE.Document.getElementsByTagName("A")
For n = 0 To objA.Length - 1
If InStr(objA(n).OuterHTML, "キーワード") > 0 Then
objA(n).Click
Exit For
End If
Next
Set objA = Nothing
このあとにデバックしてしまいます…
0096デフォルトの名無しさん2015/12/12(土) 02:09:55.86ID:D2WGnzzU
>>95
>>デバッグになってしまい
エラーになるって意味かな?

エラーになるコードはどれ?

もしかして
Set objA = Nothing
した後でobjAへオブジェクトをセットしないで
objA使ってたりしない?
0097デフォルトの名無しさん2015/12/12(土) 13:20:27.33ID:7OCEnpiZ
ttps://www.youtube.com/watch?v=M5MzENXybf0
これってどうやって作ってる?
0098デフォルトの名無しさん2015/12/12(土) 13:33:18.20ID:Yc8YF04u
>>97
作った本人に聞くべきだけど、たぶん普通のゲームの作り方そのままじゃないの。
0099デフォルトの名無しさん2015/12/12(土) 20:28:13.88ID:/A1wTFJW
>>93
回答ありがとうございます。
やってみます。
0100デフォルトの名無しさん2015/12/12(土) 22:56:55.45ID:rj6YNvj2
>>97
全く分からない。最初見たとき、エミュレータにExcelに見えるガワみたいなものを持たせたのかと思ったけど、
選択されたCellに対してのみBGが配色されているところ、BGの中でも木やブロックに配色の影響がないところを見ると、単純にエミュレータと言う訳でも無さそう。

ただ2面目でExcelの操作中にマリオが少し動くところを見ると、Excelとマリオは別スレッドで動いているのかもしれない。そうなると、
マリオはExcelの機能で動かしている訳ではないのではないかと思える。

でもここまできっちり作るには、もしエミュレータを利用していたとしても、少なくともファミコンのパレット機能を知っていなければならないし、
エデイト機能も持たせてあると言っていることから、
BGとその当たり判定のメモリへの展開も知っていることになる。

でも多分この人は自前で作ってるっぽい。何故ならCellの配色がBGの更に後ろにあって、Excelの機能と思しきものがファミコンの機能と思えるところの
更に奥に食い込んでいるように見えるから。

結論を言うとちょっと信じがたい話だけど、見よう見まねか、解析したか分からないけど、マリオをOpenGLみたいなものでキチンと作って
それをExcel上で動かしているのではと推測する。でもあくまで俺の推測だから本当のところは分からないよ。
0101デフォルトの名無しさん2015/12/19(土) 09:12:27.95ID:C2ZsZsZc
プログラマはMacを使ってるってマジ?
http://hayabusa3.2ch.net/test/read.cgi/news/1450395043/
0102デフォルトの名無しさん2015/12/19(土) 11:11:30.68ID:9nLc0qec
そんなんは業界によるし職場による
0103デフォルトの名無しさん2015/12/19(土) 17:17:12.17ID:t89iAcrU
>>89
IComparer インターフェイスが使えるかってこと?
よくわからないけど無理なんじゃないかな。
自分はArrayList知らなかったので比較演算子も含めてライブラリでほげふがしてる。
0104デフォルトの名無しさん2015/12/20(日) 00:57:16.89ID:zSz2t60X
>>103
試してないけど出来るんじゃないかな




.Netフレームワークインストールしてること前提だけど
0105デフォルトの名無しさん2015/12/20(日) 01:05:44.36ID:3zlmhSVS
>>104
出来るのなら可能性とし色々広がりそうだ。
ただソートやreverseするため(だけ)にデータ構造としてArrayListクラスを使うのを強いられるのはちょっといやだな。
0106デフォルトの名無しさん2015/12/20(日) 14:32:56.31ID:JRgauTa2
エクセルマクロで辞書を使用した関数を作成したいんですが
エラーが出て困っています
エラー内容は引数は省略できません
というものなのですが
引数は特に指定していないので間違っていないと思うのですが
何がまちがっているのでしょうか?

-呼び出し側
Dim myDic As Dictionary
myDic = CreateDictionary()

-関数
Function CreateDictionary() As Dictionary
Dim aDictionary As Dictionary
Set aDictionary = New Dictionary

With aDictionary
.Add Key:="key1", Item:="value1"
.Add Key:="key2", Item:="value2"
End With

Set CreateDictionary = aDictionary
End Function
0107デフォルトの名無しさん2015/12/20(日) 14:35:48.69ID:JRgauTa2
事故解決しました
呼び出し側にsetって書いたらエラーが消えました

でも理由がわかりません
functionの場合は常にsetで代入しないといけないんでしょうか?
0108デフォルトの名無しさん2015/12/20(日) 15:42:29.15ID:g0mIqi7V
>>107
関数の戻り値の型がオブジェクトだから(Dictionaryオブジェクト)
0109デフォルトの名無しさん2015/12/21(月) 11:44:54.68ID:0jWvYEdM
Cells(r, 1) = Cells(r, 2) + Cells(r, 3) + Cells(r, 4) + Cells(r, 5)・・・
とやっていって最高いくつまで足せますか?
0110デフォルトの名無しさん2015/12/21(月) 11:53:17.32ID:dc09zofZ
>>109
VBEの文字数限界の話?やってみるしかないんじゃね?
0111デフォルトの名無しさん2015/12/21(月) 12:57:48.76ID:VBR60bJo
VBEでは1行は半角で65535文字まで
次の行に継続した場合の制限は非公開
0112デフォルトの名無しさん2015/12/21(月) 13:31:34.58ID:VBR60bJo
違った
物理行は1024バイト
論理行は65535バイト
0113デフォルトの名無しさん2015/12/21(月) 21:17:23.77ID:GVmX1WAG
?Join(repeat("a",1024),"")
aaaaaaaaaaaaaaaaaaaaaaaaaaaa・・・
a

となったから1023バイトまでだな
0114デフォルトの名無しさん2015/12/21(月) 22:31:21.13ID:ilnG5VR/
2010のVBEで試してみたけど、行末にアンダーバーが書けるのは連続で24行まで、つまり行の継続は25行までだった
行継続文字は2バイト消費するから、実際に使えるのは1021*24+1023=25527バイトってことになる

MSDNに書いてある「1行=65535バイト」ってのは到達できないと思われる
0115デフォルトの名無しさん2015/12/21(月) 23:10:27.03ID:ilnG5VR/
で、いくつまで足せるか実験しようとしてテキストエディタで書いたソースをVBEにコピペしようとしたらExcelが落ちた
こんな簡単な足し算一つで落とせるとは、意外だったわ

もしかして>>109は、このことをわかってて質問したのか?
0116デフォルトの名無しさん2015/12/21(月) 23:13:43.52ID:ilnG5VR/
再度実験中

とりあえずCells(r, 453)までは大丈夫
今んとこソースの計算式は1023文字×7行
0117デフォルトの名無しさん2015/12/21(月) 23:20:59.48ID:ilnG5VR/
513でエラーが出た
というわけで、1論理行の計算式で足せるのは512まで
つまり右辺に書けるRangeオブジェクトは511個まで

Cells(r, 1) = Cells(r, 2) + ・・・ + Cells(R, 512) まで

どうやら式が長すぎると一時的に作られるRangeオブジェクトがワークエリアを食い尽くすらしい
VBEの文字数の限界とはまったく関係ないところでひっかかるとは知らんかった
まだまだ勉強が足らんな
0118デフォルトの名無しさん2015/12/21(月) 23:34:01.24ID:ilnG5VR/
せっかく作ったんで512までのコード貼っとく
http://codepad.org/Dx6bniP1
0119デフォルトの名無しさん2015/12/21(月) 23:55:25.73ID:GVmX1WAG
好きだねアンタw
0120今日から俺は2015/12/22(火) 00:29:32.95ID:1Uckp5vQ
自作した画像を貼り付けるエクセルマクロです。
http://ww10.puny.jp/uploader/download/1450711580.zip
パスワード:abc


エラー処理に問題がないか、
アドバイス頂けませんでしょうか?

標準モジュールの
'<サブ処理(1)>
Sub 画像貼付〜
のエラー処理なんですが、

プログラマーの方のアドバイスを頂きたいです。
0121デフォルトの名無しさん2015/12/22(火) 11:18:45.06ID:1IjfeHrT
>>120
メイン関数が600行もあるので、内容は見る気まったくしない。

気づいた点:
・2行とか3行の連続した空行があるが、気持ち悪いのでやめて欲しい
・1個50行未満程度のFunction/Subに分けろ。そうすれば第三者も読む気になる

個人的な好み:
・変数宣言は必要になった場所で行え。そうすれば多少関数が長くなっても何十も変数宣言が続くことはなくなる
0122デフォルトの名無しさん2015/12/22(火) 11:30:47.44ID:71TpXAZk
平均10行未満、最長30行くらいで頼む。
0123デフォルトの名無しさん2015/12/22(火) 11:37:34.62ID:1IjfeHrT
画像貼付()で気づいた点(内容はほぼ見ていない)
・Tabキーでインデントしろ(普通は4つのスペースでインデントされる)
・不明な変数名(いきなりDnameって何?となって読む気かなりダウン)
 → コメントを入れるより、適切なネーミングで
・Dim CellWidth, CellHeight As Long
 CellWidthはLongにならない
・SheetをActivateする必要があるか?(RangeをSelectする必要があるか?)
・コメントされたコードは削除しろ
・「一旦画像をシートに貼り付け」とか書いてるが、なぜそうするのか意図不明

内容を全く知らないコードを読むのは、100行あたり10分から1時間程度かかる。
人に見てもらいたいなら、見てもらえるように努力しろ。
0124デフォルトの名無しさん2015/12/22(火) 12:08:50.62ID:71TpXAZk
一般論だがローカル変数名なんてどうでもよくない?
Function/Sub名と引数名は重要だけど。
0125デフォルトの名無しさん2015/12/22(火) 12:29:08.69ID:eV+iF7ba
俺も見ようとしたけど空のウィンドウがいくつも開きっぱなしになってるのが気になった
仕事なら他人のソースでも必死に解読するけど、これは暇つぶしにできる範疇を超えてるは
0126デフォルトの名無しさん2015/12/22(火) 13:06:10.62ID:1IjfeHrT
>>124
Dnameは画像貼付()の第一引数。
引数名もひどいが、ローカル変数名もひどい。

> 一般論だがローカル変数名なんてどうでもよくない?
一般的にはどうだかわからないが、個人的にはどうでもよくない。
ネーミング超重要。
0127デフォルトの名無しさん2015/12/22(火) 13:28:33.58ID:71TpXAZk
>>126
そうなのか。
自分は逆だ。
名付けることが必要なローカル変数が発生すること自体避けたいタイプ。
0128デフォルトの名無しさん2015/12/22(火) 13:47:37.98ID:1IjfeHrT
>>127
一般論じゃないの?

それは一般的なのかみたいな不毛な議論したくないから曖昧な表現にしたが、
ローカル変数とはいえ、ネーミングに気を遣うのは良い習慣。
0129デフォルトの名無しさん2015/12/22(火) 14:15:48.13ID:6+FfHGxJ
むしろこれをどういう用途で使うのか気になった。
0130デフォルトの名無しさん2015/12/22(火) 14:25:32.96ID:toHtA+zz
VBAってIf文やFor文等のブロック内で変数宣言しても、そのブロック内だけのスコープにならないんだよね
結局1関数内に複数の処理があって、2箇所以上で使う変数は関数の先頭で宣言してる
0131デフォルトの名無しさん2015/12/22(火) 14:56:45.78ID:1IjfeHrT
>>130
ローカル変数のスコープとコードの読みやすさについては、「変数のスコープを小さくする」で
ググることをお勧めする。

ローカル変数宣言・定義を関数の先頭で行うのを強制される言語以外では、スコープを最小と
することが推奨される。
0132デフォルトの名無しさん2015/12/22(火) 15:12:03.64ID:71TpXAZk
>>130
確かにその点は困りものだ。
別な変数を使えばよいのだが、あまり綺麗ではない。
0133デフォルトの名無しさん2015/12/22(火) 17:04:33.32ID:EK9FZmu1
>>131
>ローカル変数宣言・定義を関数の先頭で行うのを強制される言語
べつにVBAは関数の先頭での宣言を「強制」なんてされないが、スコープは狭い方が良い
ただし、VBAにはブロックレベルのスコープがないだけ
関数の先頭での宣言が「薦められていた」のは
スコープの先頭で、そのスコープ内の変数まとめて宣言した方がわかりやすいよね、って言う事

つかローカル変数定義を関数の先頭で宣言する事を強制される言語ってたとえば何?

>>130,132
まあ、そういう時は関数分けろってのが一般的な解決法なんじゃね
0134デフォルトの名無しさん2015/12/22(火) 17:24:02.60ID:1IjfeHrT
>>133
VBAの「変数のスコープ」は、宣言・定義した位置から下だよ。
だから、関数の先頭じゃなくてもっと狭められる。
0135デフォルトの名無しさん2015/12/22(火) 17:48:13.32ID:nxtSgXHp
>>134
ブロックレベル、というのが通じてないのかな?
つまりひとつの関数の中で、

For Each z ・・・
Dim tmp As Variant
・・・
Next z

For Each z ・・・
Dim tmp As String
・・・
Next z

というように変数tmpが2回宣言出来ればいいのに、それが出来ないことを嘆いている。
0136デフォルトの名無しさん2015/12/22(火) 17:50:28.23ID:1IjfeHrT
>>135
> ブロックレベル、というのが通じてないのかな?
いや、通じてるよ。

だからといって
> 結局1関数内に複数の処理があって、2箇所以上で使う変数は関数の先頭で宣言してる
とするのではなくて、もっと変数のスコープを狭めた方が良いといってるんだけど。
0137デフォルトの名無しさん2015/12/22(火) 17:57:48.82ID:1IjfeHrT
まとめると、

ローカル変数定義を関数の先頭で宣言する事を強制される言語(*1)は
しかたがないので変数の宣言は関数の先頭でするしかない。

*1) Ada由来言語とか。PL/SQLとか。

そうではない言語では、なるべく変数のスコープを狭めるのが良い。

・関数ブロック内のどこででも変数定義できるのなら、なるべく利用する直前で宣言する
・ブロックスコープが存在する言語では(C系とか)は、そのブロック内で宣言する

VBAはブロックスコープが存在しないが、関数ブロック内のどこででも変数定義できるので、
なるべく利用する直前で宣言するのが良い。

例外はJavascriptで、ホイスティングによりブロックスコープ内で宣言した変数のスコープは
関数スコープにまで拡大する。
それにより
・それでも利用する直前で宣言するよ派
・知らない人がいるかもしれないので、関数の先頭でまとめてするよ派
が存在する。
0138デフォルトの名無しさん2015/12/22(火) 18:50:23.05ID:EK9FZmu1
>>134
厳密には、VBAでは変数宣言(定義)は必須ではないので
変数定義の位置によってスコープが変更されるようなことはないだろう

Option Explicitオフで宣言前に変数を使用してた場合、エラーになるのは変数宣言の方
つまり変数宣言以前にそのスコープにその変数が存在している

まあ、Option Explicitはオンで使うべきではあるんだが

>>137
VBAではブロックスコープは存在しないので
「関数ブロック内のどこででも変数定義できる」(ただし利用は定義後のみ)

「なるべく利用する直前で宣言する」のではなく、関数の先頭で宣言する事が薦められていた

MSがそう勧めてたこともあるので、VBAプログラマの多くは関数先頭宣言派だと思うぞ

まあ俺は最近は使う直前宣言に改宗したがw
0139デフォルトの名無しさん2015/12/22(火) 19:27:38.21ID:nxtSgXHp
スコープを狭めたことには全然なってないので、俺はだいたい先頭で宣言するけど例外もある。
というかプロシージャの長さによるね。10行越えたらちょっと考える。
0140デフォルトの名無しさん2015/12/22(火) 19:41:14.20ID:eV+iF7ba
宣言しなくても使える、とはちょっと違うんだけどな
VBAの変数宣言は記述を省略できるだけで、変数を使った時点でVariant型として自動的に宣言される
コードに書かなかった場合はシステムが代わりに宣言しといてくれるんだよ
このソースを実行してみればわかる

Sub Macro1()
  a = 1  ' ← 変数を使おうとした時点で、書かなくても自動的に Dim a As Variant が実行される
  Dim a As Variant  '←宣言が重複するのでエラーになる
End Sub
0141デフォルトの名無しさん2015/12/22(火) 19:54:40.62ID:7wWwuT9q
>>138
> Option Explicitオフで

今時あり得ん
議論する価値もない
0142デフォルトの名無しさん2015/12/22(火) 19:57:05.43ID:EK9FZmu1
じゃあ言い方を変えてあげよう
スコープを狭めるとかいうのは間違いで、スコープは言語によって定義されていて
宣言位置や方法なんかによってどのスコープか決定されるだけだ
VBAで一番狭いスコープはプロシジャレベルなので、どこで宣言しようがそれよりスコープが狭まることはない
狭まるのは利用可能範囲だけ

まあ、利用可能範囲をスコープというならそれでも良いかという気がしてきたからもうどうでもいいやw
0143デフォルトの名無しさん2015/12/22(火) 20:04:19.43ID:nxtSgXHp
しかしVBAでタイプセーフとか言う気は起こらないのであった
0144デフォルトの名無しさん2015/12/22(火) 20:10:47.37ID:nxtSgXHp
ん、Option Explicitのことだったか。
ならそんなものほとんどつける意味ないし無駄。
0145デフォルトの名無しさん2015/12/23(水) 00:21:34.23ID:e7byjM9n
>>144
必要の根拠しめせないけど、
意味ないし無駄という根拠示せる?(Option Explicitを付けないメリット)
煽りじゃないですよ。
0146デフォルトの名無しさん2015/12/23(水) 00:41:23.47ID:M5GRmAfS
>>145
自分の経験上、一度も役立ったことがないというのが根拠。
付けないことにメリットがあるとまでは言ってない。
エディタの設定でOption Explicitはついているのだが、これまで一度も「変数が定義されていません」のエラーを出したことはない。
つまりDimし忘れることなんて普通は起こらないし、それへの保険なんて任意保険で十分。やらないのはあり得んみたいな言説はおかしい。
0147デフォルトの名無しさん2015/12/23(水) 05:36:21.78ID:zGgTg8AL
むしろ自分はOption Explicit付けないこと無かったから、
変数宣言しなくてもエラーにならないなんて忘れてたわ。

田中さんはこんな風に言ってるな。
http://officetanaka.net/excel/vba/beginner/11.htm

因みに余談だけど、.NetになるとOption Strictと言うのがあって、Option Explicitと一緒に書かれることが多い。
これは実行時バインディングで型が決まるものや、暗黙の変換を許可するかしないかを決めるものだけど、
型推論によって実行時バインディングで型を決めざるを得ないときもあるので、基本、付けると言うスタンスに留まることが多いかな。つまり、絶対ではない。

ただ、VBAであれ.Netであれ、Option Explicitに関しては今まで付けておいて困ったことはないな。
変数宣言も型も、明示的に設定していることが前提なら付けておいた方がいいだろな。
大丈夫な人は大丈夫なんだろうけど、それは「俺は今まで簡単なロジックでバグを出したことが無いから、
簡単なロジック部分のテストケースは作らない」と言ってるのと同じだな。
その人の信用性も有るんだろうけど、Option Explicitが付いていれば「ちゃんと変数宣言してますよ」と言うことの担保にもなる。

それでも、「いや、俺は絶対そんなミスは犯さないから付けない」と言うのであれば、もうそれ以上言うこと無いし。
最も大概の仕事場のコーディングルールでは付けることになっていると思うけどね。
0148デフォルトの名無しさん2015/12/23(水) 09:46:21.95ID:QfnO5T+O
「俺は忘れないから大丈夫」

若いっていいなあ
0149デフォルトの名無しさん2015/12/23(水) 10:49:34.08ID:e7byjM9n
んーいろいろ参考になった。
みなさんレスどうもです。
俺はつける派かなOption Explicit
0150デフォルトの名無しさん2015/12/23(水) 10:54:12.55ID:M5GRmAfS
>>148
つけて助かったことあるの?
結局Optiob Explicitなんてシートベルトの価値ではなくて、チャリンコの補助輪の価値しかないと思う。
デフォルトで付けいて放置してるけどさ。
0151デフォルトの名無しさん2015/12/23(水) 12:18:30.14ID:QfnO5T+O
なんだただのギャグか
0152デフォルトの名無しさん2015/12/23(水) 12:29:09.66ID:MZJ58G0+
スコープの話出てたけど、普通あるのにVBAになくて困るものとして定数(const)が欲しい。
VBAのConstは定数式を与えなきゃならないので使いにくい。
■ このスレッドは過去ログ倉庫に格納されています