Excel VBA 質問スレ Part51
■ このスレッドは過去ログ倉庫に格納されています
スレ立ての際は一行目に !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総合相談所 126 https://mevius.2ch.net/test/read.cgi/bsoft/1496487719/ ※前スレ Excel VBA 質問スレ Part50 http://mevius.2ch.net/test/read.cgi/tech/ VIPQ2_EXTDAT: checked:vvvvv:1000:512:----: EXT was configured 👀 Rock54: Caution(BBR-MD5:0be15ced7fbdb9fdb4d0ce1929c1b82f) >>211 現在のcolumns(2)の中身が左にずれるか、そのままか、かな? 当てずっぽうだけど。 >>204 >>210 アドインをあきらめます。 ありがとうございました。 エクセルVBAですがあるシートで入力し別のシートに転記するというコードを記入しているのですが For文でやろうとするとうまくいきません。元々のシートの行が11行目から始まり転記先のシートが2行目から始まるのでネストを使って以下のようにコードを組んでみたのですが2行目の入力データが転記先のデータに2行追加されてしまいました。 1行目と2行目はそれぞれ別のデータが記述されておりそのまま転記できるようなコードにしたいです。 もしかしたら、そもそもforだとだめなのかもしれません。ちなみに入力するデータが11行目から始まり終わりは20行目で終わります。 がとりあえず繰り返し構文でできればかまいません。下記のコードをどう変えればいいか教えてください。 Sub 登録() Set syougai = Sheets("障害記録") 'シート名にて指定しているので変更しない事 Set itigi = Sheets("一時データ") 'シート名にて指定しているので変更しない事 Const hiduke As Long = 19 '日付列の定数 Const gouki As Long = 17 '号機の列の定数 Const era As Long = 18 'エラーコードの列の定数 Const hyou1 As Long = 11 '障害集計表上の定数 Const kisyu As Long = 21 Const syuukei1 As Long = 21 For i = 2 To 3 For j = 11 To 12 itigi.Cells(i, 1).Value = syougai.Cells(j, hiduke).Value '日付 itigi.Cells(i, 2).Value = syougai.Cells(j, gouki).Value '号機 itigi.Cells(i, 3).Value = syougai.Cells(j, kisyu).Value '機種 itigi.Cells(i, 4).Value = syougai.Cells(j, era).Value 'エラーコード itigi.Cells(i, 5).Value = syougai.Cells(j, syuukei1).Value '集計データ i = i + 1 j = j + 1 Next j Next i End Sub 〉〉214 ネストの使い方間違ってると思うのですがどう直せばいいのかわかりません。 >>214 itigi じゃなくて itiji にしろ シート名「にて」はやめてシート名「で」にしろ i = i + 1 と j = j + 1 は不要なので消せ >>214 単純にシートで開始行がずれているだけなら For i = 2 to 3 itigi.Cells(i, 1).Value = syougai.Cells(i +9, hiduke).Value 以下略 Next でいいんじゃないでしょうか ループはネストすると 内側のループだけ全部回して外に抜ける、を外のループの回数 だから、ネストでは意図した動作にならないでしょう >>216 も言っているけど、Nextで変数に勝手に+1されるから足さなくていい てか hiduke なんて変数名使うくらいなら「日付」のほうが10倍まし そもそもVBAでやることなのかな 転記先の一時データのシートのセルに障害記録シートのセルを参照する式を書くだけで良くない? >>214 値を取得しながら転記しようとするから混乱する コレクションなり配列なりに一回格納してから転記するようにすればネスト要らん >>221 変数名は大事でしょ こいつの変数の付け方は最悪に近いわ 代入の式見なかったらなんのことだかわからねー hidukeと日付のどちらか選べと言われたら、hidikeを選ぶ。 仕事内容を記録するエクセルを作成したく、 シート名は各個人名でフォームを開くボタン設置。 登録用に必要項目をフォームで作り、転記するサンプルマクロを書いたんですが、今後必要項目が増えたり、減ったりしたときに人数分フォームを弄ったりマクロ書き換えるのは面倒ななんですけど、一個をものを共有し使用するにはどうしたらいいですか? 各個人のエクセルを開き、作ったボタンで共通のエクセルを開きフォームを開いて転記させるとか? 共通のエクセルを読み取り専用で開き書き込む時に自分のエクセルを開いて転記させるとか? なんかうまいやり方ないですか? >>226 シート毎つまり人毎にボタンを作るなら そのボタンをクリックした時にその人独自の値をグローバル変数とかに代入して フォームは共通のものを呼び出す フォームに入力されたものを書き込む時は さっきのグローバル変数を見て 書き込み先のシートとかを特定する >>228 同時に複数の人がそのエクセルファイルを使わない事が前提だけど >>226 一つのエクセルファイルを複数人で同時に使うのはいろいろ大変だと思う。 共有共通にせず個人毎に違うファイルを使ってもらって、 仕事内容記録フォルダに入ってるファイル全てをまとめて集計するマクロを作った方がよさそ。 >>230 データはなんでもいいからDBに書き込んでエクセルはインプット画面として割り切りなさい マジで エクセルの共有はマジで地雷 運用を見直した方がいい >>230 入力するのが一人で他の人が見るだけなら問題ない 複数人が同時に書き込むならエクセルじゃなくて ウェブアプリとかにした方が良いと思う mdbを複数ユーザーで同時に掴めるなら、SQLでデータを投げれば動作するんじゃないの。 入力フォーム作りがクソ面倒くさいからエクセルでやるのは愚策中の愚策なのは確かだけど。 >>223 健康のためなら死ねるタイプ?w ごめんけど理解不能 どうしてもエクセルだけでやりたいなら、フォームとデータでファイル別けるべきだね >>236 いや、常識だろ 自分でメンテするにしたって嫌だわ フォームボタンをクリックした時に グローバル変数とかに時刻なり、その人のIDなりを記録して 編集中である事が分かるようにしておく 書き込んだらクリアする 他の人がフォームボタンをクリックしたら 編集中かどうかチェックして 編集中なら後で再実行するようにダイアログを出す >>238 お前の常識とか知らんし興味もない。 他人の変数名にケチ付けるのは常識じゃなくてエゴだろ React では、データアクセス(CRUD)部分は、 Flux の、Store という部分で、 UI とは完全に分離させている nmp の、immutable パッケージで、データを変更不能にしたり 変数名は結構考えるけどな。 普段なら辞書サイトでその意味の英単語から付けることが多い。 API使えば変数名の重要性が分かる。 >>243 それは変数名と言うより引数名でしょ? それだったら確かに大事 個人的に引数含む変数名に半角英字は避けるように徹底してる。 予約語と被らなくなるし徹底すれば読みやすいしね。 一般的に、名前に半角英数使うのはコンパイラが2バイト文字対応していない事が理由なんで、 対応しているコンパイラには積極的に2バイト文字で投げた方がいい。 >>244 一年前に作ったコードの宣言部分と代入部分見ずになんの値か把握できる自信があるならどうぞ まだシステムハンガリアンの方がポリシーあるだけマシ >>246 俺が>>244 で言った意図は、「引数名は大事だがローカル変数名はたいして大事じゃない」という意味だ。 それに反論しているのかな? 大事じゃない変数なんてないんだよ みんなそれぞれに役割があって、一生懸命に生きてるんだから >>248 それは違うだろ まあ、使い捨てのテストなんかは適当にやるけど 長い変数名が嫌なのは打つのが面倒だからなんだろうけど、そもそも同じ変数が何度も出てくる時点でリファクタリングの臭いがするわけでな >>250 ローカル変数に限っていうなら、上の方がよくて下に行くにしたがって悪くなると思っている ・ローカル変数がない ・tmp とか a とか x とかいう名前で十分わかる ・適切な名前をつけることでよくわかる ・適切な名前がつけられていないことで混乱する ・適切な名前がつけられているにもかかわらず混乱する そうだよね? >・適切な名前をつけることでよくわかる >・適切な名前がつけられていないことで混乱する 同じことじゃね? >>252 いや、 やれば改善する可能性があるのにやっていない状態、ということで下位になっている >>251 ローカル変数がないの意味がよくわからん 値渡しの引数はローカル変数なんだけど それを除外したとしても、変数なしで書ける処理は限られてくるし >>256 不要な変数を作るなってことだろ そのまま代入すりゃいいのに>>222 みたいにいったん変数に格納したがる奴は一定数いる >>251 tmpとか、座標系の短い変数はきちっと関数化して処理の分断ができてるときに限るけどね 大体そんなもんじゃないかな >>257 配列に格納してから云々はそれぞれの処理を独立させることであとから見通しがよくなるんだよ たとえば、代入する値に条件付きで何らかの処理を加えなきゃいけなくなったときなんかにループしながら直接吐き出してるとネストが深くなって可読性が低くなる それぞれ独立してれば関数化するのも楽だしな >>259 > たとえば、代入する値に条件付きで何らかの処理を加えなきゃいけなくなったとき その時にやればいいだけ >>260 一回変数にいれることでそれがなんの値か、というのを明示するって意味もある 意味があるからやってんだよ >>256 日付が変わっているからIDは違うが、元の俺の発言は>>248 の >「引数名は大事だがローカル変数名はたいして大事じゃない」という意味だ。 なんだよね。 つまり引数は別として狭い意味のローカル変数について語っている。 それと、>変数なしで書ける処理は限られてくるし については、良い〜悪いの序列の話なので、「変数なしで書けるくらいスコープが狭い方が良い」ということさ。 ( ・ω・)∩シツモーン 範囲A1:C10の値をまとめてD1:F10に代入するときにさ 直接=で結ぶと駄目で 一旦変数で tmp=range(A1:C10).value range(D1:F10)=tmp とかいうふうにすればオッケーなのって何でなのん? >>264 Range(A1:C10).Value = Range(D1:F10).Value でいけると思うけど? ごめん逆 >>264 のやりたいことは Range(D1:F10).Value = Range(A1:C10).Value だね 値のコピーは Range("D1:F10") = Range("A1:C10").Value 範囲が同じなら R1.Value=R2.Valueで行けるな、普通に Set R1=R2はなんか無理 R1=R2でいけない理由はよくわからん RangeオブジェクトのデフォルトプロパティってValueだよね? >>268 Rangeの既定のプロパティは、ドキュメント上だとItem 実際はちょっとトリックがあって、_Defaultっていう隠しプロパティ こいつがアドレス指定しない場合はValueを返す >>268 Setを使うということはオブジェクトということだぞ。 それはRangeそのものを代入することを意味する。 A1セルにB1セルを代入など出来よう筈が無い。 A1セルのアドレスがB1? 意味不明だろ。 >>270 rangeオブジェクトの実体はアドレス情報ってことか? >>273 ??? それだけじゃねーだろ。 が、それも含むのは当然。 indirectとかsumproductとか、便利なんだけどいまいちよく解らんよな。 >>270 Set の左辺は変数だから当然と言えば当然 A1セル自体は変数じゃなくてオブジェクトだからな >>274 いやまあ、セル同士を直接セットが無理っぽいのは何となく感覚でわかるんだが、どういう動きでそうなってんのかなーって気になるわけよ Range()みたいなのって返却値がRangeクラスなだけあってRange()自体は関数だから Rangeオブジェクト Rangeプロパティ Range関数 Rangeでチン これが区別できれば完璧 >>279 getRangeにしとけよな 紛らわしいわ リストを絞り込み別のリストで1行だけを表示できるようにしたらどうしたらいいでしょうか? わかりやすくいうと、sheet1にA1からZ1000までのリスト置き、それを何らかの方法で絞込 sheet2のEの1にE列の絞り込んだ1行目をEの2にF列の1行目を表示し次へを押すと2行目を表示するようにしたい オートフィルみたいなことですが表示したいセルが文文章で多くそのセルだけを表示できるようにしたいです。 1行だけならなんとなくわかるのですが次の行にコマンドボタンを押すことで表示する方法はイメージできません。 for文ならiを使えばいいんでしょうけどやりたいことと違う >>283 Find関数使って検索してヒットした行数を返すようにして、 受け取った行数を元に情報を取得、次へボタンはFindNextにしておく。 というのが一番簡単かなぁ。本当はExcelじゃなくてAccessで扱う方がやりやすいんだけど。 以下不明点を教えて 1なぜ変数を初期化するのか? 2なぜNextjでjだけループが終わるのか? 3If Hantei Then (もしも変数の場合は。。。) もはや意味がわからない 初心者にもわかりやすく答えよ Sub CorrectCode() Dim i As Long Dim j As Long Dim Hantei As Boolean '変数の値を初期化する Hantei = False For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row For j = 2 To Cells(Rows.Count, 3).End(xlUp).Row If Cells(i, 1) = Cells(j, 3) Then '変数に"True"を代入する Hantei = True Exit For End If Next j If Hantei Then '変数の値を"False"に戻す Hantei = False Else 'セルの背景色を変える(チェックする) Cells(i, 1).Interior.ColorIndex = 6 End If Next i End Sub >>285 Next j の捉え方からすると、そもそも実行の順番が分かっていないようなので基礎からやる事をおすすめする。 俺なりに日本語訳してみた 間違っていたら教えてくれ VBA初めて3日です 基礎は本読んでるからわかっている 変数宣言 変数に初期値を入れる わかりやすいように 変数iは2から一番下からみて最初に値の入ってセルまでをループする 変数jも同様 もしもA列とC列にループする上で同じのが見つかったら 変数にTUREを入れる そしてループを抜ける そんでまたjのループを繰り返す もしも変数がTUREをもっていたら FALSEに変える → なぜ? セルの色を変える そんでiのループを繰り返す 初期値をfalseにする理由 trueの時は色づけという流れにしたいので、予めfalseにしておく必要がある boolean型の初期値はtrueなので。 途中でfalseを入れる理由 i=1 のままで j を最終行までループさせてチェック その次に i=2 にして j を同じく最終行までループさせてチェックするのだが i=1 でのチェックが終わった結果 true なら i=2 でのチェックに備えて false に初期化する必要がある これは基本的に最初の初期化と同じ考え方 Hanteiの初期化、j のループの直前に置けばIf文の後の変数初期化がいらなくなる気がする・・・ >>288 なるほどわかりやすい このプログラムを日本語化して >>285 最初の変数初期化は全く必要無い。 そもそもこういうBooleanな変数を用意することに疑問。 こういう変数は、どうにもそれが無いとプログラムが組み立てられない時に使うべきで、出来るなら使わない方向で組み立てるべき。 そして、やってる内容を見ればこんなもの使わない方向で組み立てられる。 こういうコードはやりたいことを論理的につめられていない時に安易に書き出してしまった時になりやすい。 はっきり言ってクソコード。 全く参考にならん。 1.最初の初期化はいらん。 宣言後の初期値はFalseだから。 逆に初期値をTrueにする場合は初期化が必要。 途中の初期化については、jに関する1つの処理が終わった時にTrueになってたら次の処理の結果がおかしくなるから必要。 2.Exit Forのことを言ってるなら最も内側のFor Nextから抜けるからとしか言えん。仕様だね。 3.If〜Thenは〜がTrueかどうかを判定している。 If i=0 Thenはiが0だったらと考えがちだが正しくはi=0の文がTrueかどうかを判定している。 イミディエイトウィンドウに?(10=10)と入力してEnterキーを押すとTrueとなるし?(10=5)と入力してEnterキーを押すとFalseになる。 >>285 同じこといってるかもしれんけどこの場合変数Hanteiが丸々要らない if文の中にセルの色変更のコードを書けばいい 仮に、この変数がいるとしてもどんな値が入っててもどうせfalseにするんだからif分岐してる意味がわからない もっと言うとHanteiとかいう変数名がクソ過ぎる なんの判定かさっぱりわからん canChangeColorとかnotMatchValueとかしとけば目的が分かりやすいのに A列の各セルの情報と合致するものが、C列に一件も無かった場合、 次に合致するデータが現れるまでA列の背景色を変え続ける という処理なのでHanteiが要らない様に書き換えるって難しい気がするんだけど。 >>293 ごめん、そこちゃんと読み込めてなかったわ 一致したら変えると勘違いした なんにしてもフラグの初期化は頭かケツでいいと思うけど 似たようなソースコードを作ってみました なぜだかエラーがでます Sub test() Dim i As Long Dim j As Long Dim U As Long For i = 1 To Cells(Rows.Count, 1).End(xUp).Row For j = 1 To Cells(Rows.Count, 3).End(xUp).Row If Cells(i, 1) = Cells(j, 3) Then U = 1 End If Next j If U = 1 Then U = 0 Else Cells(j, 3).ColorIndex = 3 End If Next i End Sub >>293 確かに一致したものが無かったらだからBoolean使う方が自然か。 使わなくても簡単だけど自然なBoolean使うのが正しいわ。 俺も勘違いした。 ちなみに、一致せずに全てチェックしてjのループを終了した場合のjの値を調べればBooleanはいらんし、そもそもFind使ってループ1つにしてもいらん。 この仕様を見た場合、絶対こんなコード書かないけど、俺が書くとした場合の配列にぶちこむ方法はBoolean使うのが自然だな。 ちなみにランダムで10000行にデータ入れた場合、このコードで320秒、Find使う方法で22秒、配列入れる方法で9秒だった。 小学生がなんで3×5が15になるの?って聞いてるのに 俺なら電卓で答えだすぜ!って息巻いてる人のようにみえる 学習の初段階でつまずいてる人への的確な回答ではないわな なんつうか、これが俺の後輩なら、フローチャート書いてみって言いたくなるな もうフローチャートなんて10年以上見てないけどな >1なぜ変数を初期化するのか? あってもなくてもこのコードなら動くけど すべての言語が変数を初期化してくれるわけではないので、変数は必ず自分で初期化しろって作法もある 自分で初期化すれば、初期値を間違えて覚えていたりしてもバグになりにくいしな(Booleanの初期値はFalse) >2なぜNextjでjだけループが終わるのか? ちょっと質問の真意がわからん ForとNextは1対1で対応するんで、Next jならjのループ終端だぞ >3If Hantei Then (もしも変数の場合は。。。) もはや意味がわからない IfとThenの間に書くのは、条件式と呼ばれる式(文じゃないよ) 式の値がTrueかFlaseで条件分岐する そして変数はそれだけで式として成り立つ。この場合は変数の内容そのものが式の値 If Hantei=True Thenって書いても良いんだけど、(とくにBooleanに対する=Trueは)冗長だと言って嫌う作法もある VBAはExcelが現役だから、いつまでたっても入門者が一定数いるよなぁ はっきり言えば、今どきのブログラムの勉強にはVBAは向かないよ ブック名 C:\book.xlsx シート名 データ 説明文パート 1〜5行目 データパート ..ヘッダ A6〜Z6 ..データ A7〜Z* ..データ件数 不定 プロバイダ Microsoft.ACE.OleDB.12.0 このような設定でヘッダとデータをselect文で全件取得するにはどうすればいいですか? >>299-300 超初心者の話かよ。 VBAエキスパートの話じゃなかったんか? あと、If Hantei Thenを分からないって言ってるのは感覚の話で、君の説明じゃ分からないと思うぜ。 Hantei=Trueという式自体に値があって、それが正しい場合にその値は(Hantei=True)=Trueという結果になっているということが感覚的に分からないと理解できんだろ。 初心者はHanteiとTrueが等しかった場合と感覚的に理解してるんだから。 その感覚ではIf Hantei Thenが理解出来ない。 >>301 SQLで任意のセル範囲を取得する場合はFROM文で取得出来たはず。 SELECT * FROM [ データ$A6:Z1000] みたいな形。 ただその条件だとデータベースに投げる前にエクセル上で整形した方が効率いいと思うけど。 if hentai = true then 変態は正義 まず>>285 のプログラムを動作順に日本語訳してくれよ >>305 簡単だろ。 A列のそれぞれのセルに対してC列に同じ値が無かったら色を付けてる。 1.A2からA列の最終セルまで1つ1つのセル(以下Aiとする)について以下を繰り返す。 2.C2からC列の最終セルまでにAiと同じ値が有ったときHanteiをTrueに設定。 3.HanteiがFalseの場合(C列にAiと等しい値はなかった場合)はAiに色を付ける。 4.HanteiがTrueの場合はFalseに設定。(どんな場合だろうがFalseに設定したいが、既にFalseなのにFalseに設定する必要は無い。単にFalseに初期化してるだけ。) 5.Aiの次のセルに対して繰り返し処理続行する。 >>302 「VBAエキスパート」という資格の勉強をしている超初心者の話だろ? VBA始めて3日と書いてるし エキスパート名乗ってる割にはバグくさいコードなんだよな。 If Not Hantei Then Cells(i, 1).Interior.ColorIndex = 6 Hantei = False っていう書き方がたぶん本来意図した仕様に近いと思うんだけども。 >>307 勉強してる奴が質問してるんであって、 このコードはそいつが書いたもんじゃない。 VBAエキスパート公式ってんだから、 資格の参考書かなんかに載ってるんだろ。 >>308 いや、この書き方自体は良くあるよ。 あんたのも間違いじゃない。 ○○でもわかる ○○のすべて ○○エキスパート ○○完全ガイド こういうタイトル付いてるのは初心者向け ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.1 2024/04/28 Walang Kapalit ★ | Donguri System Team 5ちゃんねる