X



Excel VBA 質問スレ Part51

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん (スププ Sd4a-O827)
垢版 |
2017/11/08(水) 11:26:30.13ID:+KUB1/9hd

スレ立ての際は一行目に
!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)
0192デフォルトの名無しさん (ワッチョイ 7f3f-h3cN)
垢版 |
2017/11/23(木) 13:05:29.27ID:IQVJTYbd0
>>190
簡単に書くとこんな感じの関数です。

Function Kubun(code as string) as string
if (left(code,3) = "123") then Kubun = "A"
end function

if文が大量に続くので共通化してアドインで配布しようと思ってます。
これをKubun.xlbとしてアドインフォルダに保存しました。

新規BookでセルA1に123、セルB1に =Kubun(A1) と入力したところ
セルB1にAと表示され、関数は機能しました。
その後保存した新規Bookを開き何もせず閉じようとすると保存確認メッセージがでます。
0193デフォルトの名無しさん (ワッチョイ 5feb-g2WY)
垢版 |
2017/11/23(木) 13:22:13.30ID:fJlhhdGs0
>>192
再計算されてるから
値は変化しないけどセルの内容は更新されていると予想
0195デフォルトの名無しさん (スップ Sd7f-cUxe)
垢版 |
2017/11/23(木) 14:06:43.11ID:1VQF43Qed
>>192
xlbってなんだっけ?
xlamじゃないの?
0196デフォルトの名無しさん (スップ Sd7f-cUxe)
垢版 |
2017/11/23(木) 14:07:06.07ID:1VQF43Qed
かぶった
0197デフォルトの名無しさん (ワッチョイ 7f3f-h3cN)
垢版 |
2017/11/23(木) 14:35:16.43ID:IQVJTYbd0
すいません。拡張子は違ったかもしれません。
0198デフォルトの名無しさん (ワッチョイ 67f7-hcjg)
垢版 |
2017/11/23(木) 15:49:16.74ID:AvEDQSYF0
>>192
ネットで検索してみると回答は>>193氏の「再計算」で正解だと思うよ
そのユーザー定義関数の中で使ってる関数の中に再計算が発生する関数が含まれているのでは?

簡単な例でいくと新規ブックのセルA1に=TODAY()と入力し確定、そのブックを保存し閉じる
そのブックを開くとTODAY関数による再計算が発生するため何もせずに閉じようとしても保存確認出る
それと同じことでは
0199デフォルトの名無しさん (ワッチョイ 7f3f-h3cN)
垢版 |
2017/11/23(木) 17:02:33.93ID:IQVJTYbd0
>>198
192の通り使っているのはif文とLeft関数だけです。
試しに関数の中の処理を全て消してみたのですが、
状況は変わりませんでした。
0201デフォルトの名無しさん (ワッチョイ bf9d-h3cN)
垢版 |
2017/11/23(木) 17:22:13.82ID:k3nQdCAx0
>>199
おそらく

A1が変わってないときに、=Kubun(A1) という式が必ず同じ値を返すという「保証」ができないので
B1セルが変更されている可能性を排除できない
ということで変更されている(可能性がある)と判断されてる

ユーザ定義関数は中身チェックしないで非決定的だって判断だな
シート開くときに再計算するかどうかのオプション設定なかったっけ?最悪手動かな
0202デフォルトの名無しさん (ササクッテロレ Spfb-g2WY)
垢版 |
2017/11/23(木) 17:30:51.41ID:JDomtUrWp
>>199
その関数にDebug.print 文を仕込んでおいて
呼ばれたかどうかを確認してみたら?
0203デフォルトの名無しさん (ワッチョイ 7f3f-h3cN)
垢版 |
2017/11/23(木) 19:42:47.05ID:IQVJTYbd0
>>201
保存確認メッセージを防ぐ方法はないですかね?

>>202
関数は呼ばれていますが、それだと何か方法ありますか?
0204デフォルトの名無しさん (ワッチョイ 5feb-g2WY)
垢版 |
2017/11/23(木) 20:00:32.08ID:fJlhhdGs0
>>203
関数が呼ばれると言うことは変更されると言うことだから
保存確認ダイアログが出るのが普通

savedプロパティを変更する方法とか
calculationプロパティをマニュアルにする方法とか
方法はあるかもしれないけど
他の問題が起きるようになるかもしれない
0206デフォルトの名無しさん (ワッチョイ 27a4-cUCq)
垢版 |
2017/11/24(金) 11:41:27.83ID:h1FhSyIp0
質問です。Excel 2016で、Autofilerされたシートの内容を参照するために

(wsはワークシートオブジェクトです)
Debug.Print ws.AutoFilterMode     →この結果は True
Debug.Print ws.AutoFilter.FilterMode  →この結果も True
Dim rgFilter As Range
Set rgFilter = ws.AutoFilter.Range.Columns(1).SpecialCells(xlCellTypeVisible)

For Each e In rgFilter
  Debug.Print e
Next e

こんな感じで参照しようとしてるんですが、
参照してるシートでフィルターが掛かっていても、いなくても
同じように全件(25行なら25行)がイミディエイトに表示されます。
絞り込まれた結果のみを表示するためにはどうしたら良いのでしょうか?
0209デフォルトの名無しさん (ワッチョイ 27a4-cUCq)
垢版 |
2017/11/24(金) 12:12:04.66ID:h1FhSyIp0
Dim MaxRow As Long
MaxRow = ws.Range("A" & Rows.Count).End(xlUp).row

これを追加して、
Set rgFilter = ws.Range("A1:A" & MaxRow).CurrentRegion.SpecialCells(xlCellTypeVisible)

にしてみても、結果は>>206と同じになりました。
んー謎です
0211デフォルトの名無しさん (イモイモ Se0f-u0W/)
垢版 |
2017/11/24(金) 16:52:13.42ID:x6NJ51zce
Sheets("Sheet1").Columns(2).Insert Shift:=xlToLeft
Sheets("Sheet1").Columns(2).Insert Shift:=xlToRight

この二行の動作の差が分からないので
違いを教えてください
0213デフォルトの名無しさん (ワッチョイ 5f58-h3cN)
垢版 |
2017/11/24(金) 19:18:42.44ID:V+PY16OM0
>>204
>>210
アドインをあきらめます。
ありがとうございました。
0214デフォルトの名無しさん (アウアウオー Sa1f-h3cN)
垢版 |
2017/11/25(土) 12:49:09.41ID:roqaXNhOa
エクセル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
0215デフォルトの名無しさん (ワッチョイ 7f81-h3cN)
垢版 |
2017/11/25(土) 13:36:20.17ID:fp6T8Ewd0
〉〉214
ネストの使い方間違ってると思うのですがどう直せばいいのかわかりません。
0217デフォルトの名無しさん (ワッチョイ bf9f-5mWG)
垢版 |
2017/11/25(土) 13:55:20.06ID:QhU2UVSF0
>>214
単純にシートで開始行がずれているだけなら

For i = 2 to 3
itigi.Cells(i, 1).Value = syougai.Cells(i +9, hiduke).Value
以下略
Next

でいいんじゃないでしょうか
ループはネストすると
内側のループだけ全部回して外に抜ける、を外のループの回数
だから、ネストでは意図した動作にならないでしょう
>>216も言っているけど、Nextで変数に勝手に+1されるから足さなくていい
0218デフォルトの名無しさん (ワッチョイ 7f81-h3cN)
垢版 |
2017/11/25(土) 14:08:02.51ID:fp6T8Ewd0
ありがとうございました。
できました。
0219デフォルトの名無しさん (スップ Sdff-cUxe)
垢版 |
2017/11/25(土) 15:25:06.65ID:P/RTUJJid
てか hiduke なんて変数名使うくらいなら「日付」のほうが10倍まし
0226デフォルトの名無しさん (スップ Sd7f-P8Uf)
垢版 |
2017/11/25(土) 17:37:28.74ID:S5e4mFeJd
仕事内容を記録するエクセルを作成したく、
シート名は各個人名でフォームを開くボタン設置。
登録用に必要項目をフォームで作り、転記するサンプルマクロを書いたんですが、今後必要項目が増えたり、減ったりしたときに人数分フォームを弄ったりマクロ書き換えるのは面倒ななんですけど、一個をものを共有し使用するにはどうしたらいいですか?

各個人のエクセルを開き、作ったボタンで共通のエクセルを開きフォームを開いて転記させるとか?

共通のエクセルを読み取り専用で開き書き込む時に自分のエクセルを開いて転記させるとか?

なんかうまいやり方ないですか?
0228デフォルトの名無しさん (ワッチョイ 47b3-g2WY)
垢版 |
2017/11/25(土) 17:52:49.62ID:M1jU9gED0
>>226
シート毎つまり人毎にボタンを作るなら
そのボタンをクリックした時にその人独自の値をグローバル変数とかに代入して
フォームは共通のものを呼び出す

フォームに入力されたものを書き込む時は
さっきのグローバル変数を見て
書き込み先のシートとかを特定する
0229デフォルトの名無しさん (ワッチョイ 47b3-g2WY)
垢版 |
2017/11/25(土) 17:53:40.22ID:M1jU9gED0
>>228
同時に複数の人がそのエクセルファイルを使わない事が前提だけど
0231デフォルトの名無しさん (ワッチョイ 5faf-5mWG)
垢版 |
2017/11/25(土) 18:33:58.83ID:MqKvnHus0
>>226
一つのエクセルファイルを複数人で同時に使うのはいろいろ大変だと思う。
共有共通にせず個人毎に違うファイルを使ってもらって、
仕事内容記録フォルダに入ってるファイル全てをまとめて集計するマクロを作った方がよさそ。
0234デフォルトの名無しさん (ササクッテロラ Spfb-g2WY)
垢版 |
2017/11/25(土) 19:34:05.10ID:PrfYax++p
>>230
入力するのが一人で他の人が見るだけなら問題ない

複数人が同時に書き込むならエクセルじゃなくて
ウェブアプリとかにした方が良いと思う
0235デフォルトの名無しさん (ワッチョイ 7fb9-+V5r)
垢版 |
2017/11/25(土) 19:37:11.17ID:T5+qbkCf0
mdbを複数ユーザーで同時に掴めるなら、SQLでデータを投げれば動作するんじゃないの。
入力フォーム作りがクソ面倒くさいからエクセルでやるのは愚策中の愚策なのは確かだけど。
0239デフォルトの名無しさん (ワッチョイ dfeb-g2WY)
垢版 |
2017/11/25(土) 20:24:47.32ID:fZkth5mu0
フォームボタンをクリックした時に
グローバル変数とかに時刻なり、その人のIDなりを記録して
編集中である事が分かるようにしておく

書き込んだらクリアする

他の人がフォームボタンをクリックしたら
編集中かどうかチェックして
編集中なら後で再実行するようにダイアログを出す
0245デフォルトの名無しさん (ワッチョイ 7fb9-+V5r)
垢版 |
2017/11/25(土) 22:00:33.02ID:T5+qbkCf0
個人的に引数含む変数名に半角英字は避けるように徹底してる。
予約語と被らなくなるし徹底すれば読みやすいしね。

一般的に、名前に半角英数使うのはコンパイラが2バイト文字対応していない事が理由なんで、
対応しているコンパイラには積極的に2バイト文字で投げた方がいい。
0250デフォルトの名無しさん (ワッチョイ 47b3-2sqJ)
垢版 |
2017/11/26(日) 09:30:00.33ID:ci9PkC0t0
>>248
それは違うだろ
まあ、使い捨てのテストなんかは適当にやるけど
長い変数名が嫌なのは打つのが面倒だからなんだろうけど、そもそも同じ変数が何度も出てくる時点でリファクタリングの臭いがするわけでな
0251デフォルトの名無しさん (ワッチョイ 5fe7-8Ex9)
垢版 |
2017/11/26(日) 11:10:58.75ID:A1ZwwN/70
>>250
ローカル変数に限っていうなら、上の方がよくて下に行くにしたがって悪くなると思っている

・ローカル変数がない
・tmp とか a とか x とかいう名前で十分わかる
・適切な名前をつけることでよくわかる
・適切な名前がつけられていないことで混乱する
・適切な名前がつけられているにもかかわらず混乱する

そうだよね?
0259デフォルトの名無しさん (ワッチョイ 47b3-2sqJ)
垢版 |
2017/11/26(日) 13:04:15.84ID:ci9PkC0t0
>>251
tmpとか、座標系の短い変数はきちっと関数化して処理の分断ができてるときに限るけどね
大体そんなもんじゃないかな
>>257
配列に格納してから云々はそれぞれの処理を独立させることであとから見通しがよくなるんだよ
たとえば、代入する値に条件付きで何らかの処理を加えなきゃいけなくなったときなんかにループしながら直接吐き出してるとネストが深くなって可読性が低くなる
それぞれ独立してれば関数化するのも楽だしな
0263デフォルトの名無しさん (ワッチョイ 5fe7-8Ex9)
垢版 |
2017/11/26(日) 15:20:43.89ID:A1ZwwN/70
>>256
日付が変わっているからIDは違うが、元の俺の発言は>>248
>「引数名は大事だがローカル変数名はたいして大事じゃない」という意味だ。
なんだよね。
つまり引数は別として狭い意味のローカル変数について語っている。

それと、>変数なしで書ける処理は限られてくるし
については、良い〜悪いの序列の話なので、「変数なしで書けるくらいスコープが狭い方が良い」ということさ。
0264デフォルトの名無しさん (アウアウカー Sadb-tRV8)
垢版 |
2017/11/26(日) 16:18:08.52ID:t/ZpdAAca
( ・ω・)∩シツモーン
範囲A1:C10の値をまとめてD1:F10に代入するときにさ
直接=で結ぶと駄目で
一旦変数で
tmp=range(A1:C10).value
range(D1:F10)=tmp
とかいうふうにすればオッケーなのって何でなのん?
0270デフォルトの名無しさん (ワッチョイ bf9f-n8us)
垢版 |
2017/11/27(月) 22:21:45.18ID:HF1f2kGW0
>>268
Setを使うということはオブジェクトということだぞ。
それはRangeそのものを代入することを意味する。
A1セルにB1セルを代入など出来よう筈が無い。
A1セルのアドレスがB1?
意味不明だろ。
0277デフォルトの名無しさん (スップ Sd7f-cUxe)
垢版 |
2017/11/28(火) 09:41:03.64ID:/j8R3q5Od
>>270
Set の左辺は変数だから当然と言えば当然
A1セル自体は変数じゃなくてオブジェクトだからな
0283デフォルトの名無しさん (アウアウオー Sa12-9GJZ)
垢版 |
2017/11/30(木) 20:52:21.44ID:Acf/eaNYa
リストを絞り込み別のリストで1行だけを表示できるようにしたらどうしたらいいでしょうか?
わかりやすくいうと、sheet1にA1からZ1000までのリスト置き、それを何らかの方法で絞込
sheet2のEの1にE列の絞り込んだ1行目をEの2にF列の1行目を表示し次へを押すと2行目を表示するようにしたい
オートフィルみたいなことですが表示したいセルが文文章で多くそのセルだけを表示できるようにしたいです。
1行だけならなんとなくわかるのですが次の行にコマンドボタンを押すことで表示する方法はイメージできません。
for文ならiを使えばいいんでしょうけどやりたいことと違う
0284デフォルトの名無しさん (ワッチョイ 66b9-MbHU)
垢版 |
2017/11/30(木) 21:50:06.23ID:ECoRVPVY0
>>283
Find関数使って検索してヒットした行数を返すようにして、
受け取った行数を元に情報を取得、次へボタンはFindNextにしておく。

というのが一番簡単かなぁ。本当はExcelじゃなくてAccessで扱う方がやりやすいんだけど。
0285デフォルトの名無しさん (ワッチョイ 2aaf-1sOs)
垢版 |
2017/12/01(金) 14:32:31.35ID:4uYh51s/0
以下不明点を教えて
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
0287デフォルトの名無しさん (ワッチョイ 2aaf-1sOs)
垢版 |
2017/12/01(金) 15:05:39.92ID:4uYh51s/0
俺なりに日本語訳してみた
間違っていたら教えてくれ
VBA初めて3日です
基礎は本読んでるからわかっている


変数宣言

変数に初期値を入れる わかりやすいように

変数iは2から一番下からみて最初に値の入ってセルまでをループする
変数jも同様
もしもA列とC列にループする上で同じのが見つかったら
変数にTUREを入れる
そしてループを抜ける
そんでまたjのループを繰り返す
もしも変数がTUREをもっていたら
FALSEに変える → なぜ?
セルの色を変える
そんでiのループを繰り返す
0288デフォルトの名無しさん (ワッチョイ eab3-JjO2)
垢版 |
2017/12/01(金) 15:48:12.50ID:AGjDU3vg0
初期値をfalseにする理由
trueの時は色づけという流れにしたいので、予めfalseにしておく必要がある
boolean型の初期値はtrueなので。

途中でfalseを入れる理由
i=1 のままで j を最終行までループさせてチェック
その次に i=2 にして j を同じく最終行までループさせてチェックするのだが
i=1 でのチェックが終わった結果 true なら i=2 でのチェックに備えて false に初期化する必要がある
これは基本的に最初の初期化と同じ考え方
0290デフォルトの名無しさん (ワッチョイ 2aaf-1sOs)
垢版 |
2017/12/01(金) 16:20:04.74ID:4uYh51s/0
>>288
なるほどわかりやすい
このプログラムを日本語化して
0291デフォルトの名無しさん (ワッチョイ 9e9f-FJWj)
垢版 |
2017/12/01(金) 16:42:02.13ID:xc+Vk5Dr0
>>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になる。
0292デフォルトの名無しさん (アウアウイー Sa7d-dPl8)
垢版 |
2017/12/01(金) 17:52:43.75ID:P9JEW6xna
>>285
同じこといってるかもしれんけどこの場合変数Hanteiが丸々要らない
if文の中にセルの色変更のコードを書けばいい
仮に、この変数がいるとしてもどんな値が入っててもどうせfalseにするんだからif分岐してる意味がわからない
もっと言うとHanteiとかいう変数名がクソ過ぎる
なんの判定かさっぱりわからん
canChangeColorとかnotMatchValueとかしとけば目的が分かりやすいのに
■ このスレッドは過去ログ倉庫に格納されています