Excel VBA 質問スレ Part70
■ このスレッドは過去ログ倉庫に格納されています
!extend:checked:vvvvv:1000:512 ↑同じ内容を2行貼り付けるナリ ExcelのVBAに関する質問スレナリ コード書き込みや作成依頼もOKナリ ※前スレ Excel VBA 質問スレ Part69 https://mevius.5ch.net/test/read.cgi/tech/1607786543/ VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured 教えて下さい。 あるシートに買物記録があり、日付や購入店、商品名や単価の他に、商品の分類という列があります。 その列には「文具」「食品」「書籍」等が入力されています。 VBAで以下の動作をさせたいです。 ↓ 別シートにあるダウンリストに、選択肢として、この商品分類に入力されている値を設定する。 重複して入力されている値は無視。入力されているすべての「分類」をひとつずつ選択肢にする。 ↑ これをどう書けばいいのか、教えて下さい。 よろしくお願いいたします。 関数でも分類列をMATCHで検索してRow()と不一致なら空白として、それを入力規則にすれば出来そう VBAでやるなら連想配列使って重複弾いて、かな >>2 もう少し個別にどの部分で詰まっているか書いた方がいいんじゃね >>2 ワークシート関数でいいなら 適当なセルに =UNIQUE(商品の分類が入力された列) と入力すると重複整理された配列が入力される プルダウンリストを作りたいセルを選択して「データの入力規則」を選択、 規則をリスト、ソースをさっき作った配列がある列にする ピボットグラフのRefresh処理が重くて困ってます 汎用的な処理中に停止すべき項目(画面描画、自動計算、イベント、アラート等)は停止させています 元テーブルの行は100程度です 処理を軽くする方法があればご教示願います >>6 ピボットテーブルの設定で「更新時に列幅を自動調整する」のチェックを外す ググるとそれ出て来るけど、あんまり意味ないよ って言いつつ効果あったら恥ずかしいけど >>7 ありがとうございます ですが 処理が重くて困っているのはテーブル(ピボットテーブルではない)から作っているピボットグラフなのです これが重かったりするんですかね…? というか元々のグラフ生成が重いのかマクロが重いのか分からん 普通に更新ボタン押しても重いの? >>11 普通に手動でも遅いです… 何かピボットグラフの設定によるものならとも思いますが… グラフ更新よりも関数で固まってる可能性の方が高いから、 一度全部の関数を削除してみて解決するか確認した方がいいと思う 自動計算切っててもピボット更新時に再計算されてる筈だし >>13 ありがとうございます ワークシート関数は使わず、計算は全部vbaでやっています 関数と言えるのはピボットグラフのグラフ部分だけです ピボットグラフのグラフ部分の関数が重くなっている可能性が考えられるかも、と思いました ありがとうございます すげえなワークシート関数一切使わんでマクロだけでやるとは 遅いとか速いとか漠然としているので何秒かかっているかもわからんし データ量やステップが増えればある程度遅くなるのは当然じゃね VBA使ってんならどの部分でどんだけ時間かかってるか測定すりゃいいだけの話なのになぜしないんだろう >>18 Refreshのところで3秒かかっています 他処理全部は0.5秒で終わります それだ! パソコンのせい ゲーミング用買えば全てにおいてスマホ級の速さだ! 5chのスレで1000まで書き込まれたスレを1から1000までコピペしてsheet1に貼り付け sheet1を特定のキーワードで検索して、書き込まれたレスと返信があったレスを抽出してsheet2に貼り付けしたいです 返信がない場合は空白と入力したいです アイデアが思い付きません、宜しくお願いします >>6 イベントやアラートって目的も無く停止しない方がいいと思うが エクセルからhtmlで保存するとき グラフが1000以上でもできますか 選択した範囲をグラフにするマクロを作りたいです マクロ記録でグラフ化するまでを記録し、それを改造してやっているのですが ' Macro1 Macro ActiveSheet.Shapes.AddChart.Select ActiveChart.ChartType = xlRadar ActiveChart.SetSourceData Source:=Range(左上:右下) End Sub 「選択してる範囲を取得」してその範囲を代入する方法がよくわかりません ActiveChart.SetSourceData Source:=Range(左上:右下) のRangeの左上、右下部分にSelection(1)やSelection(Selection.Count)を入れようとしてるのですがエラーになります チャートをセレクトしてるからセルのセレクトが外れてるんだよ Addchartの時にセレクトじゃなくてオブジェクト変数にセットして アクティブチャートの行を【変数名】.(以下略)にしてやってみ 変数にセットするときに文頭のSetを忘れないようにな エラー処理で On Error GoTo を On Err GoTo と書いていて 全く気付かずエラーになって初めて、ラベルに飛ばないので気づきました。 デバッグでは判定しないようですが、これらを事前にチェックで見つけることは 出来ないのですかね? ヤフーファイナンスの仕様が変わった?のか、 当該銘柄のページから Set FR = rngResult.Find(What:="出来高*", LookAt:=xlWhole) みたいな感じで出来高取得してたのが できなくなった どこを直せばいいのかわからん もしかしてこのやり方では 取得できなくなった? >>32 まともなコードならGoto文なんてたいしてないはずだからGoto検索して目視確認で良いんじゃね? うまくいきました、ありがとうございました もう一つ質問させてください 以下は↓の画像のようにデータを範囲選択し実行した場合、3項目ごとに3つのグラフを表示するマクロです @https://i.imgur.com/qb9quh1.jpg Sub Macro1() ' Macro1 Macro Set CTop = Selection(1) Set CLast = Selection(Selection.Count) Dim i As Integer For i = 0 To 2 y = i * 3 With ActiveSheet.Shapes.AddChart.Chart .ChartType = xlRadar .SetSourceData Source:=Range(CTop.Offset(0, y), CLast.Offset(0, y)) End With Next i End Sub ただ、データに問題があり、「行9」以降の部分を抜き出してグラフを作りたいんです そこで↓のように範囲選択をして実行したのですが、系列名が出ないのでどのデータかわかりにくいんですよね Ahttps://i.imgur.com/u2vrDOl.jpg 実際のデータは膨大なため、いちいち「行○○〜行○○まで」と数値で指定するのは難しいです できればA画像のように手動で範囲選択した場合、@のようにa,b,cと系列名が出るのが理想です .SetSourceData Source:=Range(○○) の部分をうまく変更すればいいのか、それとも .SeriesCollection(1).Name = ○○ とあとで系列名を変えるのが良いのでしょうか? >>32 インタプリタは事前に文法チェックをしないのが普通ですから、そういうのはインタプリタには無理でしょう‥‥ いまどき純粋なインタプリタなんてそうそうないけどな 一応VBAは事前にコンパイルチェックできるが、>>32 は On 変数 GoTo xxっていう文法があってそれにそっているからエラーにならない そして変数宣言を強制しても、Errって組み込みオブジェクトが宣言なしで使えるという罠 なんかコード分析するようなツールでもあれば検出できるかもしれんが、まあ標準の範囲じゃ無理だな >>35 元データと選択された表示用データを別にすればいいんじゃね いきなりアホになってコード組むのが劇遅くなりました。 きれいなコードを書こうと思ったんです。 ありがとうございました。 自分で注意深くやるしかないんですね 実行中のfunction(やsub)名を取得することは可能でしょうか? やりたいことはエラー処理時にその名称を表示したいのですが べた書きするしかないですかね Public Function test() As String On Error testErr testErrr: MsgBox "testErr" & vbCrLf & "エラー番号:" & Err.Number & vbCrLf & "エラー内容:" & Err.Description, vbExclamation End Function あくまで個人的だが MsgBox "○○で異常が発生しました." & vbCrLf & "Err:" & Err.Number & " " & Err.Description, vbExclamation, "Function test" 個人的には、だけど最終的にはエラー停止が発生せずイレギュラーの場合は自らメッセージを出して処理を終了するってするのが望ましいんじゃないかなぁ 動作確認で何実行してるか知りたいだけなら各プロシージャの頭にDebug.Printでプロシージャ名吐き出しておけばどこで止まったかが分かりやすい まぁDebug.Printって軽くはないから少し大きめのプログラムだと動作確認中は時間かかる感じになっちゃうだろうけど 確かにそうだ、異常が出ないで済むように入力データのチェックとか ファイルの有無とかを先に確認すればエラーなんか滅多に起きないからな ちゃんとチェックしてればOn Errorの出番なんか滅多にないはずだけど 複数の関数でエラーが出るなんて、あきらかに設計がおかしい >>42 そうだね。VBAと言うかVB6系のは基本ベタ書きするしかない。 例外としてクラシックASPでVBS走らせたときはエラー行を表示させることが出来る。 VB.Netになるとその辺の情報は細やかに取得出来る。 VBAはベースが古い言語だから仕方がない。 >>47 別に設計がおかしいと言うことはないよ。 これはVBAに限らず論理エラーで把握しきれないものは実行時エラーとして捕まえる仕組みは当然のように設定する場合がある。 例えばDBに繋ぎに行って繋がったけどその後で何らかしらの外部的要因で切断された場合など、 実行時エラーが発生するのでその場合は何度か再接続を試みてダメだったら初めてエラーとしてポップアップするとか。 その場合、当然データ復旧させるためにもどこでどんなことやろうとして落ちたのかの情報は重要になってくることが多い。 その他にも概ね実行時エラーは予期せず落ちるものの方が多いので むしろ状況を把握するためにも細かい情報が必要になることの方が多いよ。 それってVBAでやるようなことか? 例外処理が必要とわかってるなら.netで書いてTry Catchを使うべきだと思うが >>50 .Netの環境が選択出来る状況ならそれでもいいんじゃないの? .NetならException継承して好きにエラー設定すればいい。 けどここはあくまでEXCEL VBAのスレだからその話は置いておくよ。 後、VBAでやることかどうかと言うのはあくまで俺はだけど正直あまり選択基準にないな。 第一に要件を満たしているか、次に操作や保守がし易いかかな。まぁ、納期も重要な要素にはなるけど。 だからもし後で保守するのが楽になるなら 場合によってはエラーメッセージ出しておしまいにすることもあるだろうけど 場合によってはエラーハンドリング用のクラス作ったり、 論理エラーもRaiseして実行時エラーのように処理して一元管理したり、 後始末処理をコールバックで移譲して処理したりすることも視野に入れるよ。 Date型はミリ秒を持てないのでしょうか? エクセルシートでミリ秒まで表示できている時刻があって、そのシリアル値をVBAのDate型変数に代入するとミリ秒以下が丸められてしまいます 日付を扱うならDate型使うけど 時間を扱うならDouble型使うなぁ >>52 シリアル値で日付までが整数部で時間から小数点になるから小数点扱える型なのにミリ秒が扱えないと言うのが ちょっと引っ掛かったので調べてみたよ。 方式はセルにミリ秒まで表示出来るフォーマットを設定して(yyyy/mm/dd hh:mm:ss.000) 隣のセルにその値を代入する数式を書いて、数値で小数点16桁くらい表示するようなフォーマットを設定して、 またその隣にそのセルの値を代入してセルにミリ秒まで表示するフォーマットのセルを用意して 元の値が正しく表示されるか確認した。 で、VBAで最初のセルの値をDATE型の変数に入れてDouble型に変換したら、 キチンと2番目のセルと同じ頭になることが確認出来たので、DATE型はミリ秒まで持てることが分かった。 じゃ、何で丸められちゃうの? と言うことになると思うけど、どうやらこういうことらしい。 https://support.microsoft.com/ja-jp/topic/excel- ワークシートのセルに-vba-の日付形式またはバリアント型の日付形式を割り当てようとすると-ミリ秒が最も近い秒に丸められます-4a0af2c5-78de-762f-6431-8669890f585b >>53-56 ありがとうございます 勉強中でVBAの動きを理解したいだけで、何がしたいという訳ではないです 調べてみましたが以下の理解で合っていますか? ・シリアル値はDouble型の情報 ・日付(Date型)はシリアル値の表示形式を"yyyy/mm/dd h:mm:ss"に変更しているイメージ 内部ではミリ秒含むシリアル値を持っており、ミリ秒以下の情報が九められた訳ではない ・シリアル値とDate型はCDbl とCDateで相互変換可能。このときもミリ秒以下の情報は丸められない ・ミリ秒が丸められるのは、Date型をセルに=で代入したとき これは、Date型の表示をセルにコピーしているため ・セルにDate型でなくシリアル値を代入することで回避できる (´-`).。oO(「丸める」をどう入力したら「九める」となるのだろう・・・知らんけど) >>57 本当の意味合いではかなり違う気もするけど イメージ的にはそんな感じかな >>57 Excelの内部データ形式は突き詰めない方がいいよ。 それにセルの書式の組み合わせもあるから、初心者は気をつけてね。 ありがとうございます これ以上は突き詰めないようにします ここまで解説してるサイトはほとんど見当たりませんでしたが、 Application.Waitの引数にVBAの関数を使うと何故精度が低くなるのか?など ここまで理解して初めて分かることもあったので良かったです ちなみに丸が九になったのはパソコンで打った文章をスマホで取り込んだからですね 馬鹿は入力機器で漢字コードが決まると思っているのか 質問させてください worksheetfunctionでsumifやcountifを使用する際の範囲指定はrange(cells(),cells ())と指定する方がいいのか、cells ().resize()と指定する方がいいのか、どっちでしょう? 皆さんはどっちを使用していますか? 一般的な場合として、例えば最大行までの範囲とした場合はどうでしょうか? 初心者なので、最近、resizeを学んだばっかりなのですが、resizeの方がすっきりしてるような気がするけど、rangeの方がパッと見、分かりやすいよなぁと思いまして たしかえくせるちゅんちゅんでそんな解説記事あったよ おれは範囲指定だったらrangeかな resizeは増やす値をちゃんと考慮しないと間違えやすいんだよな >>72 その程度ならお好みでどうぞ 値貼り付けとかやる場合は、range(cells(),cells ())なんか使ってられないから、Set、Offset、Rresizeの組み合わせを使っているな テーブルにすればRangeでCellsを囲う必要がなくなるから、まずテーブルにできるかから考えてみれば 現在6秒に1回実行するマクロを組んでいるのですが、 複数のエクセルファイルを開いてそのマクロを実行すると、 マクロを実行しているファイルとは別のエクセルファイルを マウス等で触ってアクティブにすると、関係のないそのエクセルファイルで そのマクロが実行されて、肝心のマクロが肝心のファイルで実行されず、 エラーになるという現象で悩まされています。 例えば、ファイル名「A」、ファイル名「B」のエクセルファイルがあり、 ファイル名「A」の中にマクロでセルF1を6秒間隔で選択するコードがあると、 6秒間隔で更新している時にファイル名「B」を触ると(アクティブになる)、 ファイル名「B」のセルF1を選択してしまうのです。本来はファイル名「A」 で組んでいえるのでファイル名Aで実行されなければいけないのに。。。 ファイル名、シート名を指定して他のファイルでは実行できないようにコードを 入れてみたのですが治りません。どうすればよいのでしょうか? ご教授お願いします。 >>76 コードの中の全部のRangeやCellsにもブック名とシート名を書いてある? 面倒なのは分かるが意図しない動作をする時はF8で1ステップずつ挙動を確認したりデスクに適当な人形をおいてコードを1行1行何をしている行なのかを人形に対して声に出しながら説明すると原因を突き止めやすいぞ 当該ブックのアクティブ化とCallだけでやろうとしている? これかしら? Application.Run ‘パス+ブック名’!マクロ名 https://excelwork.info/excel/runmethod/ >>76 これだとアクティブなシートの[A1]に入力されます Range("A1")=1 これだと指定したファイルの指定したシートの[A1]に入力されます Workbooks("Book1").Worksheets("Sheet1").Range("A1") = 1 まーおそらく値の設定時に ちゃんとどのブック、どのシートって 設定されていないんだろうけど もっと気になるのは6秒というスパンの中で 処理が6秒を間に合わなかったらどうするのか ちゃんと考えて作っていのかってことかな 大きなお世話かも知れんけど UIAutomationでInvokeをするVBAマクロをタスクスケジューラで 日次・定時に起動しているのですがロック画面ではInvokeが実行されません 解決策をご存知でしたらご教示お願いします なんでFINDで探せないんだろ とおもったら 改行コードがはいっていたでござる やれやれ 質問です 前はExcel2010の時はレジストリを維持って、VBAファイルだけはインスタンス起動が出来るようにするとか可能でしたが 2019にするとインスタンス起動ができなくなってました。 .xlsmファイルだけインスタンス起動するとか方法はないでしょうか 回答くださった皆さん本当に有難うございます。 これから回答いただいた対処法を全て1個1個試していこうと思います。 なお6秒に一回とは、エクセルのセルに株価をリアルタイムで 反映するソフトがあるのですが、それで株のアラート機能を VBAで自作で作っているので必要なのです。 ではでは。 sheet1のA1には https://www.jma.go.jp/ 英数字 A3からA10000には、それぞれ異なるURLが記載されています B1には https://maps.gsi.go.jp/index_m.htmlhttps ://www.mlit.go.jp/river/toukei_chousa/kasen/jiten/nihon_kawa/0305_edogawa/0305_edogawa_00.htmlhttps://www.jice.or.jp/knowledge/japan/commentary03 みたいなURLが繋がっている文字列があります B2からB10000には、上の様なURLが繋がっている文字列があります A1からA3は https://www.jma.go.jp/ 英数字 B1 https://maps.gsi.go.jp/index_m.html B2 https://www.mlit.go.jp/river/toukei_chousa/kasen/jiten/nihon_kawa/0305_edogawa/0305_edogawa_00.html B3 https://www.jice.or.jp/knowledge/japan/commentary03 みたいにB列にあるセル内を分解して、分解した分だけA列にA1の文字列を補う処理 以降B10000までを処理して sheet2に記載したいのですが、どのようにすればよいでしょうか? >>91 「エクセルのセルに株価をリアルタイムで 反映するソフトがある」 こんな珍味なソフトウェアがあるのかw >>94 楽天RSS 岡三RSS。 因みに株は難しく甘い世界ではないので安易にやらないようにしましょう。 ほとんどの人が負けます。 ワークシートの一部を画像として保存する方法にChartObjectsのExportメソッドがあります が、罫線が一部消えてしまったりフォントが潰れたりして、画質が悪いのが気に入りません もっと高画質で範囲指定してスクショを保存する方法はないでしょうか? >>99 クリップボードを手作業で切り取る際、エクセルの倍率 (Ctrl+マウススクロールで変えれるあれ)を100%よりも大きい高倍率で 切り取った方が画質が良い。 従って、その画像を取得するマクロの直前に、 エクセルの画面の大きさを変えれるコードがあるので、 それを直前に入れ、それを切り取れば恐らく高画質のが出来るんじゃないかな。 最後は勿論ばい倍率をもとに戻すマクロを入れれば良いと思う。 ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる