Excel VBA 質問スレ Part52
■ このスレッドは過去ログ倉庫に格納されています
スレ立ての際は一行目に
!extend:checked:vvvvv:1000:512
と入れてスレ立てして下さい
ExcelのVBAに関する質問スレです
コード書き込みや作成依頼もOK
※関連スレ
VBAなんでも質問スレ Part2
http://mevius.2ch.net/test/read.cgi/tech/1432173164/
Access VBA 質問スレ Part1
http://mevius.2ch.net/test/read.cgi/tech/1328536426/
※前スレ
Excel VBA 質問スレ Part51
http://mevius.2ch.net/test/read.cgi/tech/1510107990/ >>4
ならお前が立て直せや無能
そしたら削除依頼だしてくるわ これはあれか、メゾット君か
パイソンスレでも暴れてるけど
笑えるわ メゾット君は恥じるって感情を持ち合わせている割に自分より上位の人間に勝てない喧嘩売るのは辞めないってのが不思議 >>10
キミが下位の人間()だから喧嘩売られるんだよw
不思議でもなんでもないよメゾット君w >>11
何が下位で何が上位なのか教えてくれよ
言葉の定義揃えてもらえないとわからないバカだから説明してくれ >>12
それは上位の人間()を定義した?>>10に聞いたらバカさん >>13
いや、それに反論した君もその定義を理解してるんだろ? >>14
馬鹿にしてるだけなんですけどw
逆に聞くけどキミは上位の人間とか本当にあると思ってるの?バカさん >>15
じゃあ何が上位で何が下位かわからずに噛みついてるってことだね
それがわかれば満足だわ、ありがとう >>16
あのー、馬鹿にしてるってハッキリ言ったよね?w
人の話ちゃんと聞こうよバカさんw >>17
定義もわからんでバカにするってどう言うことなのかよくわからんわ
メゾット君本人でもなけりゃなんも気にならないと思うんだけど
とにかく、そこはわかってないということはわかったからそれ以上興味ないわ いや、メゾット君はVBAのコードを読み書き出来ないんだから、このスレでは初歩的な事を聞いてくる初心者より下位やぞ >>18
そりゃキミがバカなんだからわかるわけないよバカさんw
面白い事言うね!さすがバカさんw >>21
むしろキミが具体的にキミ自身がバカだと考える理由を説明してくれよバカさんw
ボクはキミの自己紹介を尊重してるだけだよバカさんw >>25
メゾット君とはプログラミングについての知識が一切無いにも関わらず、このスレに三年ほど前から張り付いていて、
具体性の無い罵詈雑言をレスし続けている名無しの一人
Methodの読み方が分からず「メゾット」と呼んだ事が名称の由来
まともな社会経験が無い為なのか、実用性が極端に薄い独特な思考法で会話をしようとする為、
回線を三つほど使い回して自演している時でも本人と特定出来てしまう
偶然映り込むよう装ってロレックスの腕時計を見せびらかすように写メに撮ってみたり(映り込み方は非常に不自然)、
プログラミングの本を読んで「変数」という概念の存在を数時間で認知できたことを褒めて欲しいと再三強調したり、
どうも虚栄心が異様に強い傾向にあるらしいが、現実では満たされない為に、このスレで他人を罵倒して鬱憤を晴らしてる様だ
平日の日中は反応が無い事が多いので労働に従事しているらしい事が見受けられるが、
中古と思われる書籍しか購入していないなど、知識に対する評価が低い点から見て、社会的地位が低い仕事だと思われる
メゾット君であるかどうかに関わらず、具体的な指摘、コードの付与がないレスはスルーする事をお勧めする あれ?レス番飛んでるけどメゾット君何かレスしたの? スレ保守のついでに相手してやったのよ
以後はスルーするつもり 2点質問いいでしょうか
1.下記コードのコメントアウトで挟んだ部分の実行時間を短縮したいのですが何かいい方法はありますか?
やりたいことは各セルに@区切りで3つのランダムな数字が入った状態から、その3つの数字で入力規則のドロップダウンリスト作成→1つ目選択です(実際は1万セル前後あります)
2.複数回実行した時にかかる時間が増えていくのは何故でしょうか?
Excel2016です、よろしくお願いします
Option Explicit
Dim i As Long, start As Long, num As String, area As Variant
Sub test()
start = Timer
area = Range("B3:B5003")
For i = 1 To UBound(area)
area(i, 1) = Int(Rnd * 1000) & "@" & Int(Rnd * 1000) & "@" & Int(Rnd * 1000)
Next i
Range("B3:B5003") = area
'//////////
For i = 3 To 5003
num = Replace(Range("B" & i), "@", ",")
With Range("B" & i).Validation
.Delete
.Add Type: = xlValidateList, _
Formula1: = Replace(Range("B" & i), "@", ",")
End With
Range("B" & i) = Split(num, ",")(0)
Next i
'//////////
Range("D3") = Round(Timer - start, 2) & " 秒"
End Sub >>31
いちいちセルからデータを持ってこない
何度も同じ処理をしない
'//////////
area = Range("B3:B5003")
For i = 3 To 5003
num = Replace(area(i - 2, 1) , "@", ",")
With Range("B" & i).Validation
.Delete
.Add Type: = xlValidateList, _
Formula1: = num
End With
area(i - 2, 1) = Split(num, ",")(0)
Next i
Range("B3:B5003") = area
'////////// どうでもいいけど、セルのインデックスを文字列で指定するのは明らかにスマートじゃない気がする
確かcellsの方が多少速度早いんじゃなかったか B列固定でとりあえず動作すりゃいいってのならどっちでもいいんじゃない。
将来的に変更可能性あるなら別だけど >>34
ま、好き好きなんだけどね
自分がこのプログラム引き継いだら書き直すなって思う >>32-33
修正しました、ありがとうございます
質問2の複数回実行した時にかかる時間が増えていくのは何故でしょうか? >>36
実行毎にどんどん加算されていくんなら、なんかキャッシュしたまま離してないんじゃないの。
マクロの終わりにEndステートメント使ってみて改善するかどうかだね。 >>37
最後を
Range("D3") = Round(Timer - start, 2) & " 秒"
End '←追加
End Sub
にしたら加算されなくなりました
新規の列だとならなかったので作成したドロップダウンリストの何かが残ってるのかなと思ってたのですがEndは今回初めて知りました
みなさんありがとうございました すみません、こっちでした
Cells(4, 4) = Round(Timer - start, 2) & " 秒"
End
End Sub たぶん変数をモジュールレベルで宣言してるからじゃないのこれ
プロシージャ内に宣言して不都合なことある? >>33AやBなら列番号のでもイイかと思うけど
列が多くて256列目にとかなってくると
セルよりrangeで文字の方が追っかけ易いよ なるほど、マクロの最後にはおまじないとしてEndを書いといたほうがいいのか >>40
それだな。
プロシージャ内ならENDは要らないと思う。
END使うのは個人的にスマートじゃなくて嫌。止むを得ず止めたい処理にだけ使うけど。 >>42
普通にコーディングしてたらそんな必要はない >>41
列をループさせないかつ列名がついてないような表なら無しではないかもしれないね
列名ついてるならEnumなりユーザー定義型なりで名前つけてやるべきだろうと思うが
引数に文字列の結合式を書くことが個人的にはすごく気持ち悪いけどまあそれは人それぞれかもしれないね あとモジュールレベルの変数名はiとか他でも使うような名前にしない方がいいぞ。
他で使っちゃってたりして予期せぬエラーの原因になる。 ここで質問するか微妙ですが質問します。
エクセル起動すると
1004エラーmacrooptionsのエラーが出ます
スタートメニューのすべてのプログラムからエクセルを起動しても同様のエラーがでます
オフィスを再インストールしても同様エラーが出るのですが解決策ないでしょうか? 他のバージョンのOffice製品が混在していないか
インストールされたプログラムで「修復」を試みたか
MSの fix it も試してみるべき >>47
さらに言えば、モジュール変数はm,グローバル変数はgを先頭に付けたほうが保守しやすい(俺は) モジュール変数なら許せてグローバル変数が許せない、ということではないよな? >>52
スコープが広がるごとに許容範囲は狭まるだろ
クラス使うならモジュールレベルの変数は普通に使うつーか、使わんと大したもん作れない 自分は他のソフトを制御するのにVBA使ってるけど、モジュールレベル変数やグローバル変数を使うとインスタンスが残って不具合出ることが多かったから使わないようにしてる。
解放させる手もあるけど、タイミングに気を使うし記述も面倒。そしてなにより不具合発生原因の特定がスコープが広すぎるときつい。
だったらプロシージャ内で終わるの前提で設計する方が楽という結論になった。
あと、公式でプロシージャレベル変数が保持されることに期待するマクロは推奨しないみたいなコメントなかったっけ。 そうそう。
フォームもクラスも使ったプログラミングを始めるとグローバル変数を使わざる負えない場合がある。
下手にENDを使われると同時に開いてるアドインが使い物にならない可能性があるので注意したほうが良いかも >>55
クラスにろフォームにしろそのモジュール内で完結させるのは前提だけどね
標準モジュールでもモジュールレベル変数が有効なことがないこともないがね
完全にパブリックなグローバル変数は可能な限り使わないのが基本だろう 今までグローバル変数を使わなければ
ならなかった局面に当たったことがない
どんな時に使わなければならなくなる?
いや、いつも外部とのやり取りは
パブリックなメソッドやプロパティで
やってるんだけど >>56
ID変わったけど55です。それについては異論はないかな。
ただ>>42のように勘違いする人が出てきそうなので、ENDを使わないのも基本だとして根拠を上げてみた。
例えばアドインでは常駐フォームとかWithEventsでイベントをフックするためのクラスを制御するのにグローバル変数を使わないといけない。
しかもENDを使った瞬間に開いてるフォーム全部消えるんだよね。
せめて同一プロジェクトのみのメモリ解放だと良いんだがExcel VBA全体のメモリが開放されてしまう。
ENDはおまじないはおまじないでも、バルスだと思って使って欲しい。 Endを使われても問題が生じない堅牢なアドインの作り方としては、設定値はレジストリに保持しておいてグローバル変数はあくまでキャッシュとして使うのがいいのかな?
(グローバル変数を使う前に必ず存在チェックして、NothingやEmptyなら都度レジストリから値を読み出してインスタンス再生成) ちなみにグローバル変数と書いたけど、Endでモジュールレベルの変数もクリアされるという理解 >>57
可愛い質問やなグローバル変数もプロパティも同じ事やで
お前はまずグローバル変数使わなきゃいいってもんやないて事を覚えた方がええな >>57
確かにモジュール変数にパブリックメソッドを経由してアクセスするようにすればグローバル変数は必要ないかな。
「使わざるを得ない」という表現は撤回するよ。
>>59
アドイン開発ではそれが基本かな。
ENDに相当する「停止」ボタンをデバッグ中に頻繁に押すから事前とそういう作り方になると思う。
あとレジストリも良いけど俺はXML派かな。
理由はPC間の移行がユーザーレベルでも出来るからだけど、今にして思えばインポートはダブルクリックで出来るレジストリのほうが簡単だな。エクスポートはちょっと厄介だけど。 >>59
そんなことしなくても
ちゃんとスコープ毎に解放する作りにしとけば
いいんじゃない?
処理が走り終わったときはこれこれ、
ブックが閉じるときはこれこれ、
といった感じで プリミティブな値を保持するコンテナが欲しいとき、ほとんどの場合はグローバル変数やモジュールレベル変数を使うまでもなくセルなどに書き込むだけで事足りる
セルへのアクセス時には組み込みのイベントがいくつも走るのでそこは要注意だし、巨大な動的配列を使用する場合は処理速度の問題が出てくるけど サーバーの監視業務からいきなりVBAでデータ抽出したりする部署に飛ばされたんだけど、なんかいい勉強方法あります?
SQLサーバから引っ張ったりしてます。 endはホントに終わらせたいときにしかつかっちゃダメだろう
PCで言えば強制終了と同じようなもんだ
仕方なしに使うもんで、グローバル変数と同じように出来るだけ使わないようにするもの
少なくともおまじない感覚はダメだな エクセルはメモリを適切に解放しない事が多々あるので、Endが有効な場面もそれだけ増えるというのが困りもの すみません質問です。初心者です
曜日を順番に表示したいのですが、出てくる曜日がデタラメなのです。
どこか悪いんでしょうが、さっぱりわかりません。
ベテラン様、教えてくだされ。
Dim 年 As Integer, 月 As Byte, 日 As Byte
年=2018
月=1
i = 1
For 日 = 1 To 31
Cells(i + 3, 3).Value = Format(年 / 月 / 日, "aaa")
i = i + 1
Next >>69
適当だけどセルに設定されてる値が
日付型になってないことない? >>70
日付型にしてみたけど、やはりダメみたいです。 >>69
> Format(年 / 月 / 日, "aaa")
なんで割り算してるの? Cells(i + 3, 3).Value = Format(DateValue(年 & "/" & 月 & "/" & 日), "aaa") >>53
クラスモジュールのやつはインスタンスごとに別の実体だからモジュール変数じゃない。 >>72
>>73
うまくいきました。
助かりました、ありがとうございました。 急いでるとよく間違えるよな。しかも思い込みでミス発見に時間かかかるかる >>73
わざわざ日付を文字列にしなくてもいいよ
Cells(i + 3, 3).Value = Format(DateSerial(年, 月, 日), "aaa")
>>76
禿げ同
しょうがないので
> Cells(i + 3, 3).Value = Format(年 / 月 / 日, "aaa")
の行にブレーク掛けて止まったらイミディエートウィンドで
Debug.Print Format(年 / 月 / 日, "aaa")
Debug.Print 年 / 月 / 日
Debug.Print 年
...
ってやってる http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/bingo_game.html
すみません このページでダブルビンゴの判定を追加しようと思うのですがうまくいきません。。。 ワシはティンコを2本もっている
2本目はとっておきだ(´・ω・`)b >>79
試してないけどこんな感じかね
・関数の先頭に「Dim cn5 As Integer」を追加
・「cn1 = 0: cn2 = 0」の直前行に「cn5 = (cn1 ¥ 5) + (cn2 ¥ 5)」を追加 (「/」ではなく「¥」)
・「cn3 = 0: cn4 = 0」の直前行に「cn5 = (cn3 ¥ 5) + (cn4 ¥ 5)」を追加
・「End With」の直前行に以下を追加
If cn5 = 5 Then
.Range(cf(k)).Value = "BINGO!!"
Beep
End If >>82
間違えた
× If cn5 = 5 Then
○ If cn5 >= 2 Then クロスワードパズル、迷路探索アルゴリズムをExcelVBAで作ることができたので、
今度はテトリス作ってみようと思う。
が、飛躍しすぎ?
キー操作で回転させるとか、→押下で横に移動しつつ落下するとかは、難しそうだな。
タイマとかも張らないといけない? >>84
5年くらい前に作った。
余裕とは言わないけどぷよぷよ作るよりは楽。
タイマーはAPIで見てる。
ブロックはセルに数字を入れて
条件付き書式で着色した。
今作ればクラスの理解があの頃とは全然違うので
多分また違う作りになると思う。 テトリスってWinAPIに慣れるために最初に作るようなヤツだから構造的にはそこまで難しくないだろうな
でもエクセルだと描画速度の問題があるから・・・ >>86
大丈夫。EXCELとは言えそこまで遅くはないよ。
むしろ遅くなったら作りに問題があると考えていいと思う。 宣言済みの変数を全て初期化するにはどうしたらいいですか? >>88
律儀に全部の変数になにかを代入すりゃいいだけだろ >>89
それはそうなんですが変数を追加とかしたときに初期化漏れが出そうで・・・
その方法しかないんですかね? >>88
宣言した直後は初期化されてる
マクロの動作がすべて終了したら自動的に初期化される
マクロの動作の途中ですべての変数を初期化したいなら、初期化するプログラムをいちいち書くしかないけど、
それはもともとの設計が悪い、方針がおかしい >>90
そもそも初期化漏れってなんだ?たとえば
Dim AAA As Integer
みたいに書いてあると、マクロが実行開始された時点ではAAAは必ず0になってるんだけど
ほかの言語と勘違いしてないか 設計が悪いのは確かです。私がVBAド初心者の頃から改良・機能追加を繰り返したコードでぐちゃぐちゃしてます。Public変数だらけなんです。
まとめて初期化する方法はなさそうですね、残念ですがレスありがとうございました。 変数のスコープは短い方がメンテナンス性がいいと思います 変数の値なんて必要に応じてセットするもんだろ
なんだよ「全変数初期化」って
プログラミングの基礎からやりなおした方がいい ■ このスレッドは過去ログ倉庫に格納されています