Excel VBA 質問スレ Part53

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2018/04/27(金) 19:02:38.39ID:+ocy8bIv
ExcelのVBAに関する質問スレです
コード書き込みや作成依頼もOK


※前スレ
Excel VBA 質問スレ Part52
http://mevius.5ch.net/test/read.cgi/tech/1517052305/
2018/05/09(水) 20:43:17.83ID:z3LuxVKv
>>771
Variant配列には何が入ってるかわからんので最適化しにくい
2018/05/09(水) 20:59:13.98ID:HhkRUfwj
このように答えがついても反応しない質問者がよくいるからQA以外の話題で盛り上がる。
ま、興味深い話題ならいいんだけどね。
2018/05/09(水) 21:26:33.65ID:fZf43uAK
>>777
ループの中じゃなくね?
784デフォルトの名無しさん
垢版 |
2018/05/09(水) 21:43:05.88
>>776
ActiveWorkbook.ProtectSharing の後に
ActiveWorkbook.ExclusiveAccess を入れてみれば?

知らんけど
2018/05/09(水) 21:52:15.61ID:idFoGogH
>>778
スコープの件、了解です。
いろいろ試してみます。
2018/05/09(水) 21:53:17.93ID:idFoGogH
>>779
メモリに乗せれば単純に早くなるわけではないんですね。
787デフォルトの名無しさん
垢版 |
2018/05/09(水) 21:55:25.27ID:w1k9kHe1
>>786
配列のマッチングはどうやって書いたの?
2018/05/09(水) 21:57:44.24ID:idFoGogH
>>780
Match使うときはたいてい絶対一致でつかってました。
クロスマッチになっちゃうんでしたっけ?
ここのカキコみて、以前、高速Lookupは使ったことがあるのですが、、
半分うろ覚えです。
リストを昇順ソートして、第3引数を 1 にするだけじゃ
だめですよね。変な答えが返ってきます。
2018/05/09(水) 21:58:30.50ID:idFoGogH
>>781
そうですか。型かえてみようかな?
2018/05/09(水) 22:14:27.61ID:idFoGogH
>>787
いろいろ省略してますが、こんな感じです。

Dim rngFdList as Range: Set rngFdList= Range( ** 以下略(調査表) **
Dim arrFdList as Variant: arrFdList = rngFdList

For each r In Range( ** 以下略(駆動表) **
 With Application
 iHit = .IfError( _
    .Match(r.value, arrFdList, 0), _
    0 _
   )
 End With

 (処理...)
Next
791デフォルトの名無しさん
垢版 |
2018/05/09(水) 22:19:47.47ID:w1k9kHe1
>>790
なんだ、ワークシート関数を使ってるのか。
それじゃ配列処理にする意味ないな
2018/05/09(水) 22:23:25.94ID:idFoGogH
>>779
ああ、ワークシート上の関数と比較して、じゃなく、VBA上でMatch関数を使う際に
テーブルをRange指定するか、配列指定するかで速度が変わった、という話です。
これもマルチスレッドが関係します?

たぶんMatchの使い方がまずいんだと思いますが、、
2018/05/09(水) 22:25:05.08ID:idFoGogH
>>791
Matchのほうが早いかなと思って。
Forで回したほうが早いですかね?
それとももっといい方法が、、、
教えてください。
2018/05/09(水) 22:28:35.61ID:iSDGF1Po
>>783
本当だ
セミコロンで複数の命令繋げて
ご丁寧にインデントまで変えてあるから分からなかった
795デフォルトの名無しさん
垢版 |
2018/05/09(水) 22:49:17.51ID:w1k9kHe1
>>793
>>772>>775は理解できたの?
これに反応しないからこちらからは状況がよくわからん。
2018/05/10(木) 01:15:35.99ID:/NGeWAX7
エクセル2016や2013等の新しいエクセルで追加された関数を、
2010等の下位バージョンで動作させるような、
ユーザー定義関数が書かれたVBAモジュールを配布しているサイトってありますか?
検索の仕方が悪いのか、自分では見つけられませんでした。
2018/05/10(木) 06:25:28.16ID:hUon7v2K
>>793
セルにアクセスしてループしてるじゃん。そりゃ遅いわ。
メモリ上でループすれば速くなるよ。

処理がこれだけならセル上の関数でも工夫すりゃ同じ速度出そう。
完全一致使わない方法とかで。
2018/05/10(木) 06:42:21.45ID:n6BTi4dI
>>796
ピンポイントで〇〇の関数を2010で使いたいと言うならまだしも2013/2016の関数って一言で言われてもなぁ
799デフォルトの名無しさん
垢版 |
2018/05/10(木) 06:45:52.61
>>790
何回も検索するんならDictionary使えばいい
最初にDictionaryに登録するのにある程度時間がかかるだろうが
一回登録してしまえば検索自体は数秒もかからん
2018/05/10(木) 08:15:00.88ID:/JKhPozC
>>796
(関数名) 再現 2010
とか検索したら出てくるんじゃないかな。
IFSとか見つけたけど。
2018/05/10(木) 10:09:42.27ID:1RQmg1q/
答えがついてもろくに反応しない質問者がいるからQA以外の話題で盛り上がる

ってのは本当だな
2018/05/10(木) 10:46:30.23ID:JA/wCecl
>>776です。

>>784
ありがとうございます。
試したけどエラーになります、、、。
いろいろ調べた結果、共有設定の条件によって保存できない。
諦めます(泣)

ありがとうございました。
2018/05/10(木) 13:58:29.65ID:IeALN+vJ
>>795
二分探索は理解不十分。Matchの第3引数を0にするとバイナリサーチにはならない
んですよね。わかってないからこのザマです。ちょっと勉強してみます。
2018/05/10(木) 13:58:57.48ID:IeALN+vJ
>>797
>>797
駆動表側のこと?
今はテストなのでセル範囲だけど、実際はもっと時間のかかる別からの供給。
そしてその先にSQL処理があるので、余計なクエリを投げなくていいように篩いにかけて
おこうという意図です。
なので調査対象の表(こちらはセル範囲へ記録した履歴情報)だけでも配列に入れて
高速化しようと試みたんだけど、このザマです。
2018/05/10(木) 14:05:11.32ID:IeALN+vJ
>>797
Dicかぁ、今、ちょっと時間がとれないので、また試してみます。
早くなるかな?普通の入れ子のLoopとか、Dictionaryとか、いろいろ試してみます。
目標10sec。
2018/05/10(木) 14:06:13.75ID:IeALN+vJ
>>805
あれ、安価ミス。799への回答でした。
2018/05/10(木) 15:30:36.46ID:QBpsjCo6
SQLiteでいいじゃん
2018/05/10(木) 16:51:36.95ID:jLma9UA8
>>807
それ言えば、またこちらの環境ではセキュリティがどうのこうので入れられない〜とか言い出す奴が出てくる
んで、もうExcel限定で良いっしょ。パワーシェルキチは論外としてw
809デフォルトの名無しさん
垢版 |
2018/05/10(木) 17:47:50.99
>>805
このへん見るに、かなり高速化できそう
まあループよりハッシュのほうがそりゃあ圧倒的に速いに決まってるけど
https://excel-ubara.com/excelvba4/EXCEL268.html
2018/05/10(木) 17:54:52.83ID:7DjALtvb
エクセルマクロはやりたい放題なのにセキュリティとか片腹痛いわ
2018/05/10(木) 19:14:27.72ID:39NqoQfJ
Excel VBAで悪意のあるもの作るには本人の意思が必要。
外部ソフト入れるなら意図しないものが混入する可能性がある。
これぐらい理解できないのか?
2018/05/10(木) 19:26:28.88ID:NzRSgzkJ
オプソならすっきり解決
2018/05/10(木) 20:08:04.83ID:F9pCnCSA
>>811
内部犯やチョンボを考えられないあたりが事務員さんって感じで微笑ましい
2018/05/10(木) 21:33:49.65ID:n6BTi4dI
>>811
怪しいサイトからダウンロードするならまだわかるけどメジャーなオプソでそんなコードが見つかったら祭りになるわ w
2018/05/10(木) 21:36:46.67ID:w2ga1e/f
EXCELはWebシステムみたいに外部と繋がってないから
比較的被害は小さくて済むよね

でも以前仕事場で
内部にファイル勝手に消えたり
外部接続の無い環境でウイルスらしきものが見つかったりしたことがあって
上の人から秘密裏に頼まれてファイル監視システム作ったこともあったな
2018/05/10(木) 21:39:40.05ID:39NqoQfJ
>>813
チョンボでセキュリティを突破するようなもの作れるの?


>>814
で、どうやって有名無名を判断するの?

会社勤めしたことあるのかって発言してるよ?w
2018/05/10(木) 21:58:33.12ID:F9pCnCSA
>>816
一斉メールのBCCをCCに入れちゃったみたいなクソみたいなミスでも情報流出は情報流出
内部から持ち出すのは悪意あろうと無かろうとほんと簡単なんだよ
学生さんはのんきでいいよな
2018/05/10(木) 22:00:56.75ID:39NqoQfJ
>>817
急に持ち出す話?w
ccとかbccを覚えたてで使いたかったのかな?w
2018/05/10(木) 22:39:02.43ID:n6BTi4dI
>>815
webシステムが外部と繋がってる?
イントラも知らんのか?

>>816
判断してやるから具体的な名前だしてみ
てかまともな情シスならホワイトリストとか持ってるし
2018/05/10(木) 22:49:26.50ID:qtzmRLVh
>>819
オマエが判断するのかよw
2018/05/11(金) 00:26:28.42ID:Nk9NYlAC
揚げ足の取り合いというか、マウント合戦というか
油断するとすぐ始まるw
2018/05/11(金) 00:34:08.57ID:DwsuJYIZ
>>798,800
prototype.jsのようなVBAファイルがあればと思ったので。
個々にであればいくつか見つけているので、その都度対応するようにします。
2018/05/11(金) 01:02:06.52ID:gtt7+D13
色んなソフトがAPI公開してexcelと連動して、みたいなこと言ってるけど実際やってる人いる?
わざわざエクセルから操作する必要性が分からない
2018/05/11(金) 04:46:34.78ID:Seo60ZfW
>>823
昔、カルテサーバから翌日の輸血オーダ情報を取得して、ちょっと複雑にレイアウトしたTEPRAフォーマットに流し込んで、ハーフカットで輸血ラベルをジャンジャン印刷するのを作った記憶が。
あんまりたいした内容じゃなかった気がするけど。
それこそExcel必要?って言われるかもだけど、現場受けはよかったような。
2018/05/11(金) 05:04:34.87ID:stSNQlqp
>>819
お前の会社のイントラは世界中の晒しものになっているのか
そりゃ危険だな
2018/05/11(金) 06:51:44.72ID:CplZ+xhH
>>824
SPC9-APIとか使ってたなら.csvファイル経由でデータを渡すからExcel使うのはある意味自然だと思う
2018/05/11(金) 06:52:25.93ID:CplZ+xhH
>>825
???
ますます意味不明になってるぞ w
2018/05/11(金) 07:49:28.76ID:gtt7+D13
>>824
ありがとう
そういうちょっとした手間の省略は大事よね
もう少し探って見るわ
2018/05/11(金) 08:33:12.57ID:OTx54W6B
PSキチガイもいなくなってひと段落といったところか
何か前他の板でもPSはキチガイ独占みたいなのを見たことがあった
それは多分PowerShellとは違うPSなんだろうけど
得てしてPSと言うのはそんなんばっかだってことだろうな
2018/05/11(金) 08:45:45.24ID:xisUVEWN
何一つ言い返せなかったけどそれじゃ悔しいから敵が去った後に負け惜しみを言う人w
2018/05/11(金) 08:45:45.76ID:RS6TTfPa
>>829
お前も消えろ
2018/05/11(金) 11:08:18.88ID:Pz/tQeeR
シート1のA44:I44のセルを、マクロでシート2の最後列に貼り付けていきたいです。
下記のマクロだと、シート1のA44のセルをシート2の最後列のAのセルにのみ、コピーするだけになってしまいます。
どう変更すればいいのか、よかったら教えて頂きたいです。
よろしくお願いします。

Sub テスト()
Dim LastRow As Long
With Worksheets("シート2")
LastRow = Worksheets("シート2").Range("A"&Rows.Count).End(xlUp).Row + 1
Range("A"&LastRow).Value=Worksheets("シート1").Range("A44:I44").Value
End With
End Sub
2018/05/11(金) 11:49:30.00ID:WIuYiP4/
VBA エキスパート スタンダードより難しい資格ってありますか?
2018/05/11(金) 12:16:30.12ID:hascnQXs
>>833
えんべでっどすぺしゃりすと
2018/05/11(金) 12:17:44.23ID:Pz/tQeeR
>>832
なんでも質問スレの方に書き込みました
すいません
2018/05/11(金) 12:41:09.45ID:HsLVJmEf
>>834
VBAのスレで聞いてるんだからVBAの資格ってことだってわかるだろw
2018/05/11(金) 13:06:15.00ID:udjF1/Ux
>>836
最近はpowershellの話題も取り扱うようになったからそっちの資格かもしれない
2018/05/11(金) 19:31:54.26ID:cdAz752k
入力ヴァリデーションのやり方を教えてください

表形式のデータで1行1エンティティです
入力長さ、最小最大値、正規表現パターンなど基本的なカラムごとに独立したヴァリデーション
開始日終了日の順序などのエンティティ内の複数カラムにまたがるヴァリデーション
REST APIでサーバーに問い合わせる非同期ヴァリデーション
集計値の最大値やリレーションの存在確認など表全体のヴァリデーション
を行いたいです

入力が止まるとUXが悪化するのでエラーメッセージはメッセージボックスで表示したくありません
一定時間で消えるかフォーカスすると消滅する吹き出しのようなコントロールが理想です

これらを可能な限り宣言的にかつGUIからのチマチマとした面倒な設定は無しで実装したいです
REST APIや表全体のヴァリデーションの実体はUIと独立したCOMコンポーネントが行うので後はUIと紐付けるだけです
2018/05/11(金) 20:13:41.96ID:HsLVJmEf
>>838
文章だけで聞くレベルじゃないと思う
2018/05/11(金) 20:33:45.50ID:VErxDUwc
>>839
C#erか、Rubierか、PSerからの宿題じゃないの?
2018/05/11(金) 21:41:23.33ID:4Lj210NT
ガチガチに入力規制するなら素直にAccess使おうよ…
2018/05/11(金) 21:43:15.64ID:OTx54W6B
>>838
もう自分でやり方書いちゃってるじゃん
その通りに実装すれば良いだけじゃないの?
2018/05/12(土) 00:56:13.10ID:0dcq7Vjr
駆け出しの自分には質問内容すらさっぱりなんだが
このスレの住人はこの話の内容が理解できるくらいのレベルなの?
久しぶりに日本語が分からないって思ったわ
844デフォルトの名無しさん
垢版 |
2018/05/12(土) 01:10:53.14ID:tqwvTn43
>>838
入力したそばからバリデーションを走らせたいの?
2018/05/12(土) 04:58:53.18ID:F7D6rAHG
>>843
データベースではよくあるけど間違ってもExcelでやる事じゃないから気にしなくていいぞ
2018/05/12(土) 07:55:43.25ID:hwxaPbIq
無料の「Rails チュートリアル」で勉強すれば?
例えば、Rails で一般的な入力バリデ(validation)は、

空ではない
presence: true

1〜50文字
length: { in: 1..50 }

整数のみ
:only_integer
2018/05/12(土) 08:27:40.09ID:iloBjJ0s
>>843
Webアプリケーションなら典型的と言っていい
848デフォルトの名無しさん
垢版 |
2018/05/12(土) 09:48:01.99ID:tqwvTn43
>>838
こういうのはポリモーフィズムを利用したくなる典型例の気がする。
型ごとに checkMe メソッドを定義するとか。
ちょっと古くさいかもな。
2018/05/12(土) 10:58:14.77ID:tJgrjt+6
凄いよ
MVVMやってる横で
MVCで頑張りましょうって言われた感じ
流石PSはキチガイ独占だNE
2018/05/12(土) 11:27:49.88ID:P5sx5scC
>>849
どこにレスしてんの?
851デフォルトの名無しさん
垢版 |
2018/05/12(土) 11:31:03.75ID:tqwvTn43
>>849
MVVMってなに?(wikipediaのページを読みながら)
2018/05/12(土) 11:43:33.47ID:g9HMZZiK
>>851
京急で採用してるインバーターの事やで(大雑把なボケ)
2018/05/12(土) 19:33:17.11ID:iloBjJ0s
VBAにはMVVMもMVCもない
でも事務員さんのツールだからそれでいい
2018/05/12(土) 19:47:10.61ID:tqwvTn43
事務員て何?
システム開発の専門家以外のホワイトカラーだったら全部事務員でOK?
2018/05/12(土) 19:50:29.63ID:anlHVJo4
IT、システムが専門じゃない人でいいんじゃないの?
856デフォルトの名無しさん
垢版 |
2018/05/12(土) 21:19:03.46
Excelとパワポしか触ってないIT元請け企業の社員とかね
2018/05/13(日) 00:43:57.24ID:i7PAGBqe
過疎ってんなぁ
2018/05/13(日) 09:38:43.13ID:Mp8iXUe3
クソな話題文句の言い合いでただ伸びているよりはマシ
2018/05/13(日) 09:42:02.16ID:i7PAGBqe
クソ or 過疎ならもうスレ要らなくねえか?
2018/05/13(日) 10:08:12.60ID:V2dj1TCI
土日くらい休めよ
2018/05/13(日) 10:55:04.93ID:hA5qejl9
今までC++とかの酷い奴も来たけど
今回のPSキチガイは群を抜いて酷かったな
もう二度と現れないで欲しいよね
2018/05/13(日) 10:55:35.20ID:wyHt0Mjp
二分探索、そしてMatchでこれを活用する方法、理解できました。
・要:調査表の検索キーソート。
・検索キーが数値を含む文字列なので桁揃えする必要あり。
・Matchでは完全一致での二分探索はできないので、戻値と元値の比較が必要。
この編がポイントでしょうか。
目標10秒以内を目指し、皆さんのアドバイスを元に順に試しましたが、結局この二分探索
のすさまじい結果に驚き、辞書までは試しませんでした。多分これも早いんだろうけど、、
(つづく)
2018/05/13(日) 10:55:56.66ID:wyHt0Mjp
>>862
(つづき)
少し条件を変えて、調査表(1.4万) x 駆動表(1万)で試しました。

[線形探索]
 ・Match線形探索/調査票(Range) ... 22.9 Sec
 ・Match線形探索/調査票(Array) ... 79.12 Sec

[For入れ子]
・調査票、駆動表ともにArrayなげこみ ... 53.10 Sec
  For2重Loop。発見時、Exit Forで次へ。

[二分探索](調査票はSort済)
 ・Match二分探索/調査票(Range) ... 0.42 Sec
 ・Match二分探索/調査票(Array) ... 117.24 Sec
(つづく)
2018/05/13(日) 10:56:21.29ID:wyHt0Mjp
>>862
(つづき)
結果、RangeObjectへのMatch二分探索が最強でした。
Arrayに乗せると、どんどん結果が悪くなるのが意味不明ですが、、
Match部分に時間がかかっているのは明らかでしたが、これを二分探索にすることで
1万回のMatchが 0.4 Secで終わるというのはすさまじいですね。

最終的に、検索キーの供給とマッチング、そのあとのSQL処理まで含めて
約100 Secかかっていたのが、0.8 Secで差分処理出来るようになりました。
みなさん、アドバイスいただきありがとうございました。
2018/05/13(日) 11:03:24.93ID:i7PAGBqe
>>861
なにも言い返せなかったからなぁ
悔しいねぇ
2018/05/13(日) 13:26:19.68ID:LATlOC/3
>>864
二分探索なのにArrayでもMatch使ってるのがよくわからない。
文字列としての単純比較じゃダメなのか?
2018/05/13(日) 15:10:20.32ID:uLIKOFiX
>>864
たった一万件だろ
それなら誤差
8080の時代じゃねーよ
2018/05/13(日) 15:44:53.98ID:wyHt0Mjp
>>867
22 Sec と 0.4 Secを誤差と? すごい感覚の持ち主ですね。
2018/05/13(日) 15:48:29.20ID:wyHt0Mjp
>>866
両テーブルをArrayに乗せてForで回して単純比較したのですが、50 Secほどかかってしまったのです。
Matchを使わない場合、どう記述すればよいかわからず。
ヒントをいただけますか? もっと効率がよい方法があれば試してみたいです。
870デフォルトの名無しさん
垢版 |
2018/05/13(日) 16:14:11.00ID:+vKBH4Jv
こんな程度のどうでもよい事の効率を上げるより仕事全体の効率を上げる努力をしなさいって社長が言ってたよ
2018/05/13(日) 16:20:34.22ID:uLIKOFiX
>>868
お前のプログラムがおかしいだけだろ
872デフォルトの名無しさん
垢版 |
2018/05/13(日) 17:40:36.23ID:+vKBH4Jv
50secとか
どれだけ大規模システムを作られてるの?
もしかしてヤフーとかアマゾンとかのSE担当者さんですか?
2018/05/13(日) 17:45:12.77ID:sMzgfoge
高速化の問題は細かい情報がないと話にならんよ
テスト用データと自分が書いたコードぐらいはGithubにあげてから質問してくれ
もちろんエクセルファイルの直接交換はセキュリティなど面倒事が多いからテキストファイルでな
2018/05/13(日) 18:11:36.74ID:wyHt0Mjp
>>873
元質問は>>771,>774,
条件は >>862, >>863, に書いたとおりで
80 Sec かかったのは >>790 のコードです。

二分検索で 0.4 Secに短縮できたのは以下のコードです。関数にしました。
Function isReg(STR As String, RNG As Range) As Boolean
 Dim IDX As Long
 isReg = False
 With Application
  IDX = .IfError( .Match(STR, RNG, 1), 0 )
  If IDX = 0 Then
   ' do nothing
  ElseIf STR = .Index(RNG, IDX, 1) Then
   isReg = True
  Else
   ' do nothing
  End If
 End With
End Function

50 Sec かかった単純比較はこんな感じのForの入れ子です。
For i = LBound(arrDrvList) To UBound(arrDrvList)
For k = LBound(arrFdList) To UBound(arrFdList)
If arrDrvList(i, 1) = arrFdList(k, 1) Then
(処理)
Exit For
End If
Next
Next
どんな手法がよいか教えてください。Matchにこだわるつもりはありません。
2018/05/13(日) 18:16:05.72ID:wyHt0Mjp
>>873
あ、テストデータですね。
=TEXT(RANDBETWEEN(1,1000000),REPT("0",7))&"-"&TEXT(RANDBETWEEN(1,2),"000")
で生成できます。
駆動側が1万行、調査側が1.4万行で生成できます。
876デフォルトの名無しさん
垢版 |
2018/05/13(日) 18:18:17.66ID:LATlOC/3
>>874
それのどこが二分探索なのか俺にはよくわからない。
とりあえず自分のプログラムでArray上のデータをバイナリサーチすると、
調査表、 駆動表ともに1.4万件でやって 1.9Sec だった。(Core i5)
2018/05/13(日) 18:19:47.21ID:wyHt0Mjp
>>875
日本語おかしいな。
駆動側が1万行、調査側が1.4万行。駆動側の表から1万回Matchをかけました。
調査側の表はSort済みですが、これをArrayに投げ込んで行うとなぜが遅くなります。
2018/05/13(日) 18:22:03.91ID:wyHt0Mjp
>>876
Matchの第3引数を0以外にするとバイナリサーチになるんだそうです。

その1.9Secの結果をだせたコードの書き方が知りたいです。
2018/05/13(日) 18:24:18.63ID:sMzgfoge
>>874
動作する完全なコードを書いて
測定処理も含めたすべて
2018/05/13(日) 18:40:41.94ID:i7PAGBqe
>>874
それ線形探索
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況