Excel VBA 質問スレ Part66
■ このスレッドは過去ログ倉庫に格納されています
ExcelのVBAに関する質問スレです コード書き込みや作成依頼もOK ※前スレ Excel VBA 質問スレ Part65 https://mevius.5ch.net/test/read.cgi/tech/1584430040/ ※デフォルト設定
プロパティと引数の使い分けがいまいちわからん クラス内の一つのプロシージャで利用する変数なら引数で渡してよいの? プロパティ とりあえず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月からの均等割を割り振る。 こんな感じの事をしたいんですけど、期間の計算方法の伝授願います。 >>225 Sub Test() Dim cnt As Long Dim da As Date For cnt = 2 To Cells(Rows.Count, 2).End(xlUp).Row da = CDate(Cells(cnt, 2)) Range("B" & cnt) = da Next cnt End Sub Ruby の、clamp みたいな関数だろ clamp(min, max) -> object self を範囲内に収めます。 self <=> min が負数を返したときは min を、 self <=> max が正数を返したときは max を、 それ以外の場合は self を返します 1.clamp(0, 100) #=> 1 101.clamp(0, 100) #=> 100 -1.clamp(0, 100) #=> 0 やたらrubyで表したがるやつなんなの? 無意味だし完全にスレチなんだけど >>238 え?たかだか一つ言語知ってるだけでどや顔なんて…ありえるかもな。 >>230 説明がよくわからない。 サンプルを用意するなど、読み手にわかりやすい工夫をすること。 (期間が複数あってよくわからん、期間の基準が上中下旬なのか2023/2/12みたいな細かい日付もあるのか、 「この期間のセル数に」とか、36「マス」とか。 自分で作ったような言葉を、相手はまず理解できないと思うこと。) 最大限理解しようとして作ってみた。 https://i.imgur.com/aYLnniP.png https://i.imgur.com/Edwp9qW.png >>230 ひと月を3分割って、微妙に面倒だったりするね 質問は期間の求め方なので、こんな感じでいいと思う 簡単な流れは、月の差-1を出して*3し、開始と終了の日-1を10で割って半端な分を補正する感じ 計算上、初回分も算入する必要がある事に注意(例えば、 5/24 〜 5/24 の場合、単純に引くと0 になるから+1する必要がある) あと、月の上中下旬単位でのみ考える(2/12 は2/20と同等に扱う) Function kikan(date1 As Date, date2 As Date) As Integer Dim res As Integer res = DateDiff("m", date1, date2) - 1 'VBAでは単純な月の差なのでDay(開始日)>Day(終了日) となる場合を気にしなくていい If res < 0 Then '同じ月 res = min2((Day(date2) - 1) \ 10, 2) + 1 res = res - min2((Day(date1) - 1) \ 10, 2) Else res = res * 3 res = res + 3 - min2((Day(date1) - 1) \ 10, 2) res = res + 1 + min2((Day(date2) - 1) \ 10, 2) End If kikan = res End Function Function min2(a, b) : min2 = IIf(a < b, a, b) : End Function あと、各(月3分割)の均等割を出すとき、単純に等分した数値を次々加算していくと誤差が出る可能性があるので、その都度かけ算で計算しなおした方がいいよ 均等ではなくなることが分かっているのに均等割というのは一体 均等ではないなら分割の明確なルールと呈示するのが先だろうに select case iDay case 1 to 10 ’上旬 case 11 to 20 ’中旬 case else '下旬 end select こんなんでいいんじゃねーの 理解ができるのがすげぇよ 俺には文章から何がしたいのか分からん セルに値を手動入力中にVBAから別のセルにアクセスがあるとエラー落ちするんだけど、非同期に処理する方法はないんかね。 VBA側はインターバルタイマーでデータ処理させてて、一方でユーザーはメモ入れたり諸作業したいんだ。 vb全然知らないんだけどサクッと教えてほしい Range("C2").AutoFill Destination:=Range("C2:C804"), Type:=xlFillDefault というオートフィル用をするコードがあるとする。 このコードの804部分はいつでも固定値だからセル内の数字を参照するような可変にしたい 一応このコードの前に Volume = Range("J5").Value として数字があるセルから数値をVolumeに得てるんだけど このVolumeを804の部分に当てはめたい どうしたらいい? >>247 C2からvolume個の連続データ(volumeは可変)を作りたいんだとしたら .AutoFill Destination:=.Resize(volume) とかどうやろね >>246 セマフォ(いわゆる排他処理)をエクセルでやるのか 実現するのは結構テクニカルになるね 仮にAccessが使えるなら使ったほうがすっきりするかと volume = Range("j5") With Range("c10") .AutoFill Destination:=.Resize(volume) これでだめ? Volume = Range("J5").Value Range("C2").AutoFill Destination:=Range("C2:C" & cCtr(Volume)), Type:=xlFillDefault こういうことじゃね >>246 VBAでブックへの書き込みがないなら、外部から読み取り専用で開いてデータだけ頂いて処理する方法がある 例えばVBScriptならVBAからソースをコピペできる部分も多い 後はChangeイベントで変更が行われた時に、バックエンドとデータを同期する。 処理自体はバックエンドが行う。 サーバーは空いてるPCに(VBAで実行したければ)Excelをインストールして使えばいい。 >>240 遅くなり申し訳ないです。説明が下手すみません。後でゆっくり読んで理解してみます。 セルの入力規則の選択項目をコンボボックスのListindexみたいに番号抽出って出来ないんでしょうか "セルの入力規則の選択項目"と言っているのは、 データの入力規則ウインドウ−設定タブ−条件の設定について、 入力値の種類を"リスト"にしたときの"元の値"に入力した各値のこと? あとわざわざ番号で抽出する意味は? この"元の値"をVBAでセル(range)のプロパティから取得すると、だいたい下のどちらかのパターンのStringとなる。 1 "元の値"に入れたそのままのリスト用文字列(「a,b,c」など) 2 "元の値"に入れた参照セル範囲(「=$A$1:$A$5」など) 「番号抽出」とかいう言葉がよく分からんけど、上記で 1なら文字列を配列にするなどで解析して、セルの値(Value)で取得する 2なら参照先を取得して配列にするなどする とかで"元の値"を利用できるはず わざわざIndexを取りたいならその配列なりから取ればいい 目的がおかしくなってる可能性がある >>260 Function validFormula(c as Range) '選択セルの入力規則式を取得(簡易版) validFormula = Evaluate(c.Validation.Formula1) End Function というユーザー定義関数を用意して =MATCH(A1,validFormula(A1),FALSE) の様な感じ >>262 説明が下手ですいません やりたい事は以下のとおりです。 @表示する場合 ・機器と通信して、通信データ読み出すとIndex(数値)が取得できる。(変更不可) ・取得値が1の場合、選択リスト要素が"aa,bb,cc,dd"とするとセルにはaaが選択される。 A取得する場合 ・セルの選択リストの選択要素が"dd"だった場合、4を返すとなる ・Index=4を通信で送る コンボボックスだと楽に出来るのですが、セルを使った場合の対処に困っています。大量に項目があるのでコンボボックス一つずつ作成は対応できなくて。 PDF出力をするときに、ファイル名をBK19にして、同じフォルダ内の、 "納品書"というフォルダ内に保存したいのですが、保存場所が同じフォルダの同じ階層になってしまいます。 "納品書"フォルダに保存する方法をお願いします Dim PATH_ As String 'このブックと同じフォルダの"納品書"フォルダ 〜途中省略 PATH_ = ThisWorkbook.Path & "\" & 納品書 〜途中省略 sh.ExportAsFixedFormat Type:=xlTypePDF, Filename:=PATH_ & Range("BK19"), OpenAfterPublish:=False それと、ネット上のサンプルの中に、For文のNextの後の変数が書いていないものがありますが、どういう時に書かなくていいんですか > PATH_ = ThisWorkbook.Path & "\" & 納品書 PATH_ = ThisWorkbook.Path & "\納品書" すみませんエクセルですが教えてください セルに2020/5/25と入っている。 2020/5/25(月)というテキストにしたい。 >>267 試しましたが、納品書フォルダには保存されず、同じ階層に保存されてしまいます。 >>268 セルの書式設定から表示形式をユーザー定義の yyyy/m/d(aaa) にする ごめ PATH_ = ThisWorkbook.Path & "\納品書\" これは? >>271 ありがとうございます。納品書フォルダに入るようになりました。 テンプレから複数作ってく場合テンプレの右にどんどんコピーしていって あとでテンプレシート以外を新しいブックに保存 これだとなぁ、おばちゃんがややこしいと文句言うかも 悩むなぁ 所属してる部署や業務によってやりたい処理が違うから全部まんべんなく覚えていきたいという無駄な欲を捨てんといかんなぁ はぁぁ大学行かずに専門とかで情シス専攻すればよかった 毎回それ言うためだけに見に来てるんなら 見なきゃいいのに IT畑の人間は既存の業務フローを神聖不可侵な絶対的公理と考えてそれを自動化しようという発想をしがちだけど、それは注意が必要だと思うわ 自動化以前にそもそも無駄な業務って沢山ある 特にVBAで安易に自動化したくなるような業務はその傾向が強くて、現場の人間とちゃんと話せばあっさり消滅したりするもんだ 客の業務自体の改善に付き合うなんていうめんどくさい事はしないよ これはおかしくね?と思っても依頼されたように作るしかない ああ、上司の命令ならな。 反論しろって? 10個の工程をPGが3工程くらいに短縮すると、理解できなかったりするんだよな。 自社の業務改善って自分もしくは管理下の範疇でしかしないわな 責任取れる範囲でやらないと痛い目みるし、ドキュメントだ体制だルールだなんだ面倒だしな 基本周りは全部敵だよ >>230 Ruby で作ってみたけど、めちゃめちゃ複雑な仕様だった! 2020/05/21 〜 2023/02/12 を以下の、3つの期間に分けて、[0, 94, 5] となった! 〜2019/12/31 2020/1/1〜2022/12/31 2023/1/1〜 所定のフォルダの中に「AAA.xlsx」という名前のエクセルファイルがあった場合、そのファイルを削除し、 その後同一フォルダ内のエクセルファイルを「AAA.xlsx」というファイル名に変更する、という処理を しています。マクロ作成当初は問題なく処理できていたのですが、数日前からファイルを削除した後 実際にはエクセルファイルがあるにもかかわらず「エラー53 ファイルが見つかりません」とエラーが でるようになりました。終了ボタンを押してエラーウィンドウを閉じた後、同じ処理をすると今度は エラーが出ずに処理できます。 コード自体は変更していないのですが、このように実際には該当するファイルがあるにもかかわらず、 1度目(ファイル削除後ファイル名変更。ファイル削除処理は正常終了)はファイルが見つからずエラー、 2度目(削除するファイルがない状態でファイル名変更)は正常に処理が終了、となってしまう原因で なにか思い当たるものがある人いますか? 具体的には AAA.xlsx 20200526.xlsx ↓(AAA.xlsxを削除)←1回目はこの処理の後エラー53 20200526.xlsx ↓(ファイル名変更) AAA.xlsx となり、2回目は 20200526.xlsx ↓ AAA.xlsx で正常に処理ができます。 ファイル名変更は Name "*.xlsx" as "AAA.xlsx" で処理しています >Name "*.xlsx" as "AAA.xlsx" 何となく、この、* がヤバそうw プロパティのセットで配列や複数の引数を渡したいんだけど、送り手側の構文エラーにしかならない 調べても見つからないんだけど普通やらないの? Variantで宣言しておけば通るっぽいけど Sub テキストをエクセル() 'txtをエクセル化 With CreateObject("wscript.shell") .currentdirectory = "C:\" End With Application.Dialogs(xlDialogOpen).Show "*txt.*" End Sub 色々調べて作ってみたんですが テキストファイルウィザードのウィンドウが出て完了を押す という手間が残りやす… この手間をスキップというか直接Excelにデータ変換…教えてください また馬鹿が来た 馬鹿は何をやりたいかすら自分で把握すらしていないから馬鹿なんだよ ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.4 2024/05/19 Walang Kapalit ★ | Donguri System Team 5ちゃんねる