Excel VBA 質問スレ Part66
■ このスレッドは過去ログ倉庫に格納されています
ExcelのVBAに関する質問スレです コード書き込みや作成依頼もOK ※前スレ Excel VBA 質問スレ Part65 https://mevius.5ch.net/test/read.cgi/tech/1584430040/ ※デフォルト設定 奇天烈大百科が巻物だったら、まさしくインストロールだぞ ↓ If the eccentric encyclopedia is a scroll, it's just an installation. ↓ 風変わりな百科事典が巻物なら、それは単なるインスタレーションです。 意味がさっぱり分からなかったので、Google翻訳かけてみたら、意味が分かるようになったぞ。 textboxの値チェックがうまく行きません。20~100までの範囲を入れたいのでchangeイベントで値がこの範囲か監視してます。 100を超えていたら100に、20を下回ると20になる様にリミッタを付けました。 すると100にした後にキーボード操作で30にしようとすると、0を消した時点で強制的に20になり、そこから何か押すと100になってしまいます。 どうすれば上手くいくのでしょうか。 >>132 そういう時はスピンボタンを使った方がいいよ 馬鹿はWindowsのUIもわからず自分勝手なインターフェースを作る法則 >>136 ハゲとるやないかw 髪でうまくごまかしてるようだけど >>135 ありがとうございます コピペ対策以外は出来ました ちょっと息抜きにセルや文字の色をVBAでやろうと思ったら大きく二通りあるんだね カラープロパティとRGB関数 どっちで覚えるのが王道? いや違うか そんなに普段カラフルに使わないならカラーインデックス 細かく覚えて使いたいならカラープロパティかRGBってとこか うーん前者かな >>139 わかってない ColorプロパティにRGB関数やインデックスの値を代入するんだよ 基本的には両方使わないと色が変えられない >>141 なるほどぜんぜんわかってなかった インデックス番号で数種類覚えちゃうか RGB関数でいくつかの組み合わせ覚えちゃうか 何やろうにしても何種類かやり方があって初心者にきついわ >>142 インデックス色はカラーパレットの位置に設定してある色だから環境によっては色が変わるよ ほんと勉強になりますわ 最初は0と255の組み合わせだけでRGB関数で覚えちゃうようにしますわ この8種類くらいしか多分使わないかな どういう時どれを使うのが適しているかで選ぶのであって、どっちで覚えるとかじゃない >>145 社内のマクロツールの中味たまに見るけどなんとなく、どっちかに統一してるって感じの人が多くない? どっちでもいいんであれば好きに統一すればいいんじゃね たかが色だと思って使わないと思ってたけど メッセージボックスで黄色い部分の数値を確認後、入力とかで その範囲を真っ黄色にしてやって元に戻したり 他人、(おばちゃん)とかにはとにかくわかりやすく作るようにしてみることにした rgb値の組み合わせを覚えるのは大変なのでWebColor名で覚えるといいかも。 rgbAliceBlue rgbLightBlue rgbBlue rgbMidnightBlue みたいな感じで記述すればrgb値を指定できる。よく使うやつだけ覚えとけばいい。 vbRed 「・・・。」 vbGreen 「・・・。」 vbBlue 「・・・。」 あーおれも、基本はそのvb〜だ グラデーション的な見栄えが必要の時とかは変えるけど アクティブシートをコピーした後のコードがムズいなぁ 細かい所をいじる知識がなさすぎ 逆に原紙を作っておいて普段はそのコピーを使うようにするといい >>154 ありがとう。その方が都合そうしたよ。 シート名の取得も特定のセルから何とかできた。あとはブック名を指示したいんだけど調べりゃすぐ出てきそうだけどなかなか出て来ないわ エラー出ないように細かく作りたいもんだけ 10万円給付の紐付けなんかVBAで余裕に出来るのに話題にならないのが不思議 >>156 こういう馬鹿が職場にいて余計混乱させているだけだろ 絶対にわからん関数ばかり使ってる理解不明なコードをネットからパクって少し弄ったら完全に業務で対応できてラッキー そこから今日もユーザーフォーム適当に作ってメッセージボックスとインプットボックスを組んでいって 効率化したけど相変わらず上達せん毎日だわ >>156 1億2000万件のデータを、誤読無く、重複無く、生死の年月日まで 勘案して処理する自治体まで勘案してエクセルに食わせろとな? 相談させてください。 羅列されたデータにオートフィルタをかけて、その中でのランダム選択をシートを使わないでやる方法が知りたいです。 A列(1〜6年)、B列(1〜8組)、C列(名前) みたいな感じで、AとBから複数選択後にCから選び出す感じです。 今までは作業用のシートを設けてオートフィルタをかけたものを別シートにコピーし、その中でrandomで選んでいました。 諸事情により作業用シートが作れないので、おそらく配列内だとは思うのですが・・・・ >>163 VBAなら、とりあえず乱数を発生して、その行がオートフィルタかかってたらもう一度乱数からやり直せばいいだけ >>163 フィルタ掛けた結果をROWだけ配列に抜き出して、乱数で配列の中から一つ選べばいいんじゃね >>166 早速ありがとうございます そのままだとフィルターかけられたROWも選ばれません? オートフィルターかけた配列を一旦コピーすればいいのでしょうか? ランダム選択が目的なら、そもそも、オートフィルターにこだわる必要あるのかな? VBA使うなら、オートフィルターを扱うのは微妙に面倒だから、自前でフィルターすればいいと思うぞ オートフィルタやオートフィルタ的コードは使わない VBAのみで 乱数生成は一度きり 3桁の乱数 a を生成する まず a を6で割って余りが0〜5まででるんで 0が出たら6年 1が出たら1年 2が出たら2年 3が出たら3年 4が出たら4年 5が出たら5年 とする 例えばここで2が出て2年が選択されたら さっきの乱数 a をまた使って、組数で割って余りを求める んで同じようにして 今度は選択された組の人数で割って個人に割り当てられた番号でを特定する これを繰り返して複数人を選んでいく 選ぶ過程で同じ学年はダメとかあるなら 上の例で言えば一旦2が出たら次は2を排除するとか 繰り返し文の中で if 使って条件つけていく 学年の数、組の数、クラス人数は予めシートに表にしておくこと とかとか 6学年あって6組の学年があったりするとだめか 階層が下がるごとに乱数生成してもいいのかね A1からオートフィルターをかけて もし、変数aが空欄でなければ、B列で変数aと同じ値だけにしぼる もし、変数bが空欄でなければ、C列で変数bと同じ値だけにしぼる もし、変数cが空欄でなければ、D列で変数cと同じ値だけにしぼる というような書き方をおしえてください >>163 Dim r As Range Dim n As Long Dim i As Long With Range("A1").CurrentRegion With .Offset(1, 0).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible) n = 0 For Each r In .Rows n = n + 1 Next if n = 0 then exit sub end if n = 1以上n以下の乱数 i = 1 For Each r In .Rows If i = n Then rを使ってなにかする Exit Sub End If i = i + 1 Next End With End With >>173 まず意味が不明 →「変数aが空欄」 よくわかんないけど、 特定の表について、 VBA上で宣言した変数ごとに対応した列をフィルタする簡単なものなら書いてみた。 「空欄」の意味が不明なので、NULLか空文字か、それともセルのことだったのか、 そういうことも質問時に気にするように。 https://i.imgur.com/wNuWmnl.png 余談だがグループの中から1人をランダムで選ぶ場合、 同じことを繰り返すと同じ人が選ばれる可能性がでてくる それを無くしたい場合はシャッフルしてから順番に選ぶといい 何かをさせるときに一度リセットする的なアレですね。 プロージャくっつけて作ってる初心者だが何となくその感覚 スマホとPCのデータが両方消えて 前スレで乱数の発生教えてくれた人のコードが見れなくなったが、やべえ いや選ばれる人の立場になると、 俺前回やったのにまた俺?他の選ばれてない人はズルくね?みたいな 前スレの教えてくれた恩人のコードやっと見つけたあああああ Sub 乱数発生させる() For 項目 = 1 To 6 '項目数を変更 列 = 項目 + 2 最小 = WorksheetFunction.Min(Cells(6, 列).Resize(30)) 最大 = WorksheetFunction.Max(Cells(6, 列).Resize(30)) 幅 = 最大 - 最小 For サンプル = 1 To 25 'サンプル数 行 = サンプル + 5 If Cells(行, 列) = "" Then Cells(行, 列).NumberFormatLocal = "0.000" Cells(行, 列) = Rnd() * 幅 + 最小 Cells(行, 列) = Round(Rnd() * 幅 + 最小, 3) End If Next Next End Sub これがC6がサンプル1の項目1が始まりになるシートで使えてるんだけど これをC12からとかに変えるにはどこ弄ればいいですか? 誰かコメントをこれに添えてもらえませんか… 前スレの大恩人に救われたコードを更に流用したいです Sub 乱数発生させる() For 項目 = 1 To 20 '項目数を変更 列 = 項目 + 最小 = WorksheetFunction.Min(Cells(6, 列).Resize(30)) 最大 = WorksheetFunction.Max(Cells(6, 列).Resize(30)) 幅 = 最大 - 最小 For サンプル = 1 To 25 'サンプル数 行 = サンプル + 11 If Cells(行, 列) = "" Then Cells(行, 列).NumberFormatLocal = "0.000" Cells(行, 列) = Rnd() * 幅 + 最小 Cells(行, 列) = Round(Rnd() * 幅 + 最小, 3) End If Next Next End Sub 項目数を20に変えてC12セルから入力させたいんだけどWorksheetfunctionのとこの6と30も変えないとダメですかねこれ 乱数が狂うのかなぁ Sub 乱数発生させる() For 項目 = 1 To 20 '項目数を変更 列 = 項目 + 最小 = WorksheetFunction.Min(Cells(12, 列).Resize(36)) 最大 = WorksheetFunction.Max(Cells(12, 列).Resize(36)) 幅 = 最大 - 最小 For サンプル = 1 To 25 'サンプル数 行 = サンプル + 11 If Cells(行, 列) = "" Then Cells(行, 列).NumberFormatLocal = "0.000" Cells(行, 列) = Rnd() * 幅 + 最小 Cells(行, 列) = Round(Rnd() * 幅 + 最小, 3) End If Next Next End Sub 考えたけどこれかなぁ 他ののまっさらなシートだと乱数再現できた けど反映させたいシートだと乱数が狂う 配置も数値も同じなのに シートの設定かぁ 数千行〜数万行のデータが格納されてるシートで、 ある特定の範囲で最大文字数を取得するには 配列関数で{Max(Len(A1:A10))}とすれば良いですが(VBA上でEvaluateを用いて実装してます)、その最大文字数があるセルの場所(行番号)を特定する方法はありますか? 最大文字数のセルが複数ある場合はその全てのセルの行番号を取得したいです 最終的に、範囲内の最大文字数のセルの背景色を変えたいのが目的です >>184 セルの文字数がその最大文字数と同じなら色変えるっていう条件付き書式を設定する >>185 条件付き書式とは盲点でした。 トライしてみます。ありがとう! わかった。 けどもう後には引けんほど次元の高い事やらせてて手に負えないわ フォームのラベルに計算結果を表示について。 結果がプラスならそのまま、マイナスなら赤字にマイナス記号を付けるにはどうしたらいいですか? 例 350 -350←赤字 >>183 セル範囲の内容で乱数の範囲が設定されているからデータが入力されていないと乱数にならないのに、 そこにデータが入力されていると値が更新されない なかなかのジレンマだね 余談だけど、直感的にわかりにくいから、ループカウンタは列と行そのものにした方がいいと思うぞ あと、項目数と基準セルを変えたいなら、それを変数にして、こんな感じ 項目数 = 20 サンプル数 = 25 行0 = Range("C12").Row 列0 = Range("C12").Column For 列 = 列0 To 列0 + 項目数 - 1 ...以降も上記変数で置き換える >>190 ありがとう、全部のコード貰った後に少しずついじる事しかできないレベルだからまた挑戦してみるわ コメントしっかり残して勉強するべしですな >>190 それとこのコード見てさらっとそうやって理解できるってやっぱすごいね 仰るとおり今記入してある数値はそのまま で残りその数値を元に乱数で埋めるというのを 前スレの人が教えてくれた みんな凄いの一言 パワークエリでデータモデルに読み込んだ後ファイル移動等して元ファイルを参照できない状態からデータをシートに書き出したいのですがvbaで出来ますか? 手動では既存の接続からテーブルとして書き出せるのですがマクロ化するとクエリの更新処理でパスが見つかりませんというエラーになります >>189 その文章そのまんま単純に処理に起こすだけでいけるだろう >>194 読込時にテーブルデータを別シートにコピーするようにしとけば? >>194 Excel.Currentworkbookで、テーブルの値をパスとして読み込むようにしておいて、ファイル移動したらVBAでそのテーブルの値を書き換えるようにする 銀行まるめ型だっけ 仕事で四捨五入多用する俺はあの機能がうざすぎる Format関数使ってるけど素直にRound関数はエクセルと同じ機能にしろよマジで >>196 容量がでかいのでどうしても必要なときだけシートに書き出す形にしたいんです >>197 元ファイルは自分のローカルにあって共有フォルダで別の人が使う想定なので ある何かをやりたいときに骨子になるコードが完成するともうそこから手直しが楽しくて止まらないわ プロパティと引数の使い分けがいまいちわからん クラス内の一つのプロシージャで利用する変数なら引数で渡してよいの? プロパティ とりあえず1個ずつセットしといて、処理の開始は後回しにできる 順番を意識しなくていい 引数 複数の変数を参照渡ししたい時、構造体やサブプロパティは微妙にめんどくさい セット忘れが防げそう(願望 >>201 一応定義としては、プロパティはオブジェクトの設定や状態を見たり書いたりするものという事になってる 一度設定したら変えることが殆どない設定はプロパティ、 ちょくちょく変える設定は引数、 みたいな感じでいいと思う >>203 >>204 ありがとう 厳密に使い分けは難しそう 動くけど、他人が読んだら混乱するんだろうなと思いながら書いてる >>205 色々作ってるとそのうちなんとなくどっちにした方がいいかわかってくると思うよ 変数ってみんなどんな付け方してんの My〜とかそういう変数付けたりしてるサイトもあれば色々だね 日本語で 「わたしの〜」とかそういう変数名を付けたりしてる。 我(われ) 某(それがし) 拙(せつ) 朕(ちん) セルの数式中で条件成立時のみHYPERLINK関数を生成してるのですが、 @HYPERLINK関数が生成された事を確認 Aリンク切れが無いか確認 する事は可能でしょうか? イメージは下記ですが、数式は複数のパターンがあり困っています =if (A1<>"", HYPERLINK(A1&B1,B1),B1) 未だに二つのセルの掛け算を電卓で計算してて手入力する50歳のおじさんがいる職場なんだよな @HYPERLINK関数が生成された事を確認 -> 隣のセルに If (xxx, 1, 0) とかやっとけばいいんじゃないの Aリンク切れが無いか確認 -> マクロでHTTPリクエストしてステータスコード見ないと駄目だろうね >>205 プロパティは根幹部分を触らせるメンテ用メソッド的な意味合いで用意するといいよ。 例えば「何かを〇倍にする」というメソッドを持つクラスがあったとして、 この「何か」部分が引数で、「〇倍」部分がプロパティ。 利用者はプロパティで「〇倍」を「二倍」等に変えて異なる機能を持つインスタンスを作る事が出来る。 もちろん予め二倍や三倍に設定済みのクラスを作ってもいいんだけど、 プロパティで変更出来るようにすれば一つのクラスで済むという利点がある。 インスタンス化してプロパティを変えたオブジェクトを返す関数(コンストラクタ関数)を作れば凄く便利だよ インスタンス化は new クラス名 でオブジェクトを作ることで、 インスタンスはその作成したオブジェクトのことね ExcelVBAでCSVファイルを2次元配列に格納しようと思い、そこまで作成はできました。 ここを参照しました:ttps://ateitexe.com/excel-vba-csv-to-multi-dimensional-array/ その配列に格納した後、特定の文字列がある行を削除しようと思うと、配列だとかなり手間だと感じました。 (文字列を検索、行を削除、詰める作業が必要) だったら、そもそも配列に入れる前にそのcsvの行を無視しようと思うのですが、どうしてもうまくいきません。 どうしたらいいのでしょうか? >>216 馬鹿過ぎて話しにならない 少しは学んでから出直せ >>216 if(文字列.含んでるよ("RegExp") )then continue; で済む(VBAにはcontinue無いけど概念的には)処理を 「どうしてもうまくいきません」と言ってるわけ? 特定の文字列がある行は空にすればええやん それとも別に空の行も含まれてるんか >>216 そのどうしてもうまくいかない部分を書けよ… 例えば、Ruby で、入力ファイルが、 あ,いう a,bc 1,23 require 'csv' ary = [ ] CSV.foreach( "input.csv" ) do |row| # 1行ずつ処理する next if row[ 1 ] == "bc" # skip ary.push row # 追加 end p ary #=> [["あ", "いう"], ["1", "23"]] 要素数を変えるような操作を配列にする場合、 VBAだと大抵は新しい配列を作るような処理にしたほうが楽 foreachで条件にあえば追加する、そんな感じ 配列に入れる前にそのcsvの行を無視しようという発想は正しいと思うぞ Splitする前に文字列判定して、無かったときのみ n=n+1 まで実行するようにすればいけるはずだよ それと、ary(n, i) = tmp(i) のところは要注意 csvの列数がRedimの行で設定した数分を越えると、配列の範囲外エラーが起きるので B列の2行目から最終行に「2020/5/23」のような文字列が入力されているので この文字列を「2020/5/23」に変換するコードを教えてください >>225 Sub Sample1() End Sub >>226 >>227 すみません。「文字列を日付型」に変換でしたm(__)m >>228 馬鹿は死ねよ どうしてこう次から次へと馬鹿が来るんだ? 例 数値 1500 期間 2020/05/21〜2023/02/12 この期間のセル数に数値1500の値を 均等割で入れる場合のセル数の計算方法がわかりません。 ※用意してるセルの期間 2020年1月から2022年12月まで。 ※ひと月3分割で1年36マス。 上旬1〜10 中旬11〜20 下旬21〜末 ※2022年を超えた場合はそこまでの均等割を入れそれ以降は入れない。 ※開始期間が2020年1月以前の場合は1月からの均等割を割り振る。 こんな感じの事をしたいんですけど、期間の計算方法の伝授願います。 ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.1 2024/04/28 Walang Kapalit ★ | Donguri System Team 5ちゃんねる