X



VBAなんでも質問スレ Part2 [転載禁止]©2ch.net

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
垢版 |
2015/05/21(木) 10:52:44.71ID:KLv0vQmm
VBAを使った質問ならなんでもござれ
本来の対象であるオフィスアプリを操作する以外の話もOK

ゲーム作り、Webアクセス、外部アプリの操作
COM(ActiveX)、Win32API、.NET Framework、DirectXなどなど
VBAで実行するものであればなんでも質問してください

VBAを開発環境としていろいろ作っちゃいましょう

前スレ

VBAなんでも質問スレ
http://peace.2ch.net/test/read.cgi/tech/1342087380/

関連スレ

Excel VBA 質問スレ Part36 [転載禁止]©2ch.net
http://peace.2ch.net/test/read.cgi/tech/1419718732/

Access VBA 質問スレ Part1
http://peace.2ch.net/test/read.cgi/tech/1328536426/

VBプログラマ質問スレ(Ver.6.0 まで) part64
http://peace.2ch.net/test/read.cgi/tech/1393069842/

Excel総合相談所 118 [転載禁止]©2ch.net
http://peace.2ch.net/test/read.cgi/bsoft/1430352555/
0697デフォルトの名無しさん
垢版 |
2019/01/03(木) 16:26:50.99ID:+aY40et6
>>695
>>696
会社でとある先人の作ったエクセルのフォーマットがあるのですが、それを使って作業するおばあちゃんが度々壊してしまうのです
セル結合やセルの幅など複雑になっている物なので、壊してしまったパソコンの不得意なおばあちゃんはいつも四苦八苦していて、どうにか入力された数値以外の罫線や列幅などだけボタン1つ簡単に戻せるものを作ってあげたいと考えています

頂いたヒントを元にもう少し頑張ってみます
結局わからなければまた質問させてください
ありがとうございました
0698デフォルトの名無しさん
垢版 |
2019/01/03(木) 16:38:04.35ID:CdG5H8Qg
>>697
シートの保護じゃダメなの?
おばあちゃんには特定セルに数値入力させてるだけなんでしょ?
0699デフォルトの名無しさん
垢版 |
2019/01/03(木) 17:30:36.94ID:Em9anKIf
>>697
シート保護で十分みたいですね。
もし何らかの理由で保護できないのであれば、
同フォーマットの隠しシートから書式貼り付けした方が早そう。
セル結合もあるし、1セルずつ罫線情報取得とか効率悪すぎ。
0700デフォルトの名無しさん
垢版 |
2019/01/03(木) 22:01:21.27ID:aAVkqECP
>>698
>>699
それがわかりながらあらゆる所(不規則)を動かさないといけない時があったりで、保護だと都合が悪かったんです
フォーマット自体を大幅に変更できればもっと色々と簡単にできるのですが、それも他のおばあちゃんたちが前の方が良かった〜なんて必ず言うので見た目を崩すことはできません
担当のおばあちゃんorおばさんが変われば書式貼り付けのための範囲選択も上手くできないだろうから(全選択など知りません)また誰かが黙って長時間四苦八苦する事になってしまいます
無駄にすべて最初からやろうとしたりも平気であります
平均年齢49才の職場なので仕方ないんです
誰にも聞かずに戻したい部分を戻せるような、とーーってもわかりやすい説明付きのボタンをユーザーフォーム上にでもいくつか作ってあげたいと思っています
崩してしまうパターンはだいたい把握できているので、それが最善かなと…
0701デフォルトの名無しさん
垢版 |
2019/01/04(金) 02:06:01.37ID:+nkelZ7z
>>700
いや、だから隠しシートから自動的に書式修復をかければという意味で言うたのですが、、
トリガーはファイルオープンでも、ボタンでも。

試しにやってみたけど、罫線やセル結合は問題なく修復できるみたい。
入力規則とかは引き継げないみたいなので別にケアする必要があるかも。
行挿入、列挿入とかされて座標がかわるようなことされないならこれで十分では?

自分がよくやるのは、表のエリア毎に範囲名をつけて、そのエリア単位で最初に表組みした
ときと同じ要領で表作成を記録していき、コードを整理して修復マクロにします。
これなら起点となるセルが壊されなければ行挿入、列挿入にもある程度柔軟に対応
できるし、式や入力規則の修復も追加できる。
まぁ、利用者は作成者の想定を軽く超えてきますけどね。
0702デフォルトの名無しさん
垢版 |
2019/01/04(金) 08:59:12.57ID:jYRqvj54
>>701
理解力なくてすみません、、、
そしてありがとうございます
そのやり方を取り入れてとりあえず一度作ってみます!
0703デフォルトの名無しさん
垢版 |
2019/01/19(土) 20:28:43.04ID:gUifgf+0
ディム a アズ インテジャー
コンスト b アズ バリアント = ファルス

この読み方はあってますか?
0705デフォルトの名無しさん
垢版 |
2019/01/20(日) 08:43:51.62ID:KJwN8fo6
マジか!
自信なくなってきたわ。
フォー イーチ 〇 イン、スターコンブ、ブイビーナロウ、コンカット、
ナンバーフォーマットローカル、ドゥ ホワイル、イズナメリック、
デカー ファンクション セットウインドウロング リブ "ユーザー32" エリアス、
バイバル 〇 アズ ブーラン、アプリケーション.ハウンド、オプション エクスプリシト。
0714デフォルトの名無しさん
垢版 |
2019/01/31(木) 16:04:06.71ID:f4/Ws+Wz
パワポでExcelのVBAにある
Application.OnUndo
みたいなことって出来ない?
0717デフォルトの名無しさん
垢版 |
2019/02/01(金) 15:41:12.07ID:lbEDOgk3
>>716
そっちだね
あるいはパワポの内部変数(たとえば図形のRGB値とか)の変化を検知してイベント上げるとかでもいいんだけども
0718デフォルトの名無しさん
垢版 |
2019/02/01(金) 19:24:08.72ID:69So7CMb
質問スレでいつも思うんだけど、どんな状況でそれが必要なの?
Excelで出来るんなら、逆にExcelをパワポっぽく見せるという手もあるんじゃないの?
0719デフォルトの名無しさん
垢版 |
2019/02/02(土) 00:14:40.30ID:hkITps2T
勉強もかねてパワポのアドイン作ってるのよ
だからExcelじゃなくてパワポで出来なきゃ意味がない
その機能自体が必須で欲しい訳ではないから出来ないなら出来ないで諦める
0721デフォルトの名無しさん
垢版 |
2019/02/09(土) 00:13:31.38ID:nXE2v5Lv
Functionで値を返すのと、ByRefで返すの、どう使い分けたらいいのか、わからなくなってきた。
どっちでも返せる状況なら、どっちがいい?
0724デフォルトの名無しさん
垢版 |
2019/02/09(土) 04:25:25.62ID:6oInKB58
Function一択

ByRefは古い書き方で互換性のために残してる
これから作るプログラムには使うべきじゃない
0727デフォルトの名無しさん
垢版 |
2019/02/27(水) 18:52:45.21ID:0gstYK5t
sortのcustomorderって、セル値を入れられたりはするのでしょうか?
複数のセル値を優先順位としてデータを並び替えるマクロを作成したのですが動作が遅いので改善出来ればと考えています。(forとifで判定する手法をとっています)
よろしくお願いします
0729デフォルトの名無しさん
垢版 |
2019/03/19(火) 09:29:22.78ID:3/8oXV0g
VBAがどっとNet対応
キターーーー!
0732デフォルトの名無しさん
垢版 |
2019/03/19(火) 22:45:44.06ID:i2FNQUrb
さて、名前付き範囲ってVBA@Excelで使えないんだろうか。
もし使えたとして、実行時間はどうなのだろうか。
色々と謎が多い。
0734デフォルトの名無しさん
垢版 |
2019/03/20(水) 00:38:39.23ID:vmDq6MjZ
>>732
使えるよ
Application.Namesでコレクション取得して名前つき範囲にアクセスできるし、シートのRangeプロパティの引数ラベルとして名前をそのまま使ってセル取得できる
0735デフォルトの名無しさん
垢版 |
2019/03/20(水) 16:11:53.05ID:VkiUMgxP
>>733
横からだけど、どう面倒になるの?
0737デフォルトの名無しさん
垢版 |
2019/03/20(水) 21:06:17.96ID:ad3N4bFR
名前をキーにして名前付き範囲にアクセスするときはリスト形式になってるNamesコレクションの要素に対して正規表現か何かで逐次マッチ検索してるはずだから、名前付き範囲が増えれば増えるほどアクセスが遅くなる
0738デフォルトの名無しさん
垢版 |
2019/03/21(木) 01:35:24.94ID:XMapNPTs
なんで正規表現?
完全一致でいいじゃろ?
SortedListなら量に正比例して増えることはない
0740デフォルトの名無しさん
垢版 |
2019/03/21(木) 07:34:08.81ID:u3u8nbsq
>>737
> 正規表現か何かで逐次マッチ検索してるはずだから
なんだその意味不明な思い込みはw
普通に考えてハッシュなりB-Treeなり使ってるだろ
そもそも逐次検索だとしても遅さが気になるほど大量の名前付き範囲使う時点でなにか間違ってると思う
0741デフォルトの名無しさん
垢版 |
2019/03/22(金) 17:57:33.45ID:DJ7JSKt5
会社でブラウザの検索結果のページで
いっぱいURLのリンク先が表示されるのですが
そのたくさんのURLのそれぞれを開いたページ(毎回違うけど50ページくらいある)のデータを取得するVBAのコードを考えています。
IEの定番のCreateObject("InternetExplorer.Application")とDOMツリーの方法で実現できてはいるのですが
1つ1つページを開いて取得して閉じる、という作業がネットワークの遅さで異常に時間がかかります。
この複数のページを同時で取得する方法ってないでしょうか?よく知らないけどJavaでいうスレッドみたいな?
0743デフォルトの名無しさん
垢版 |
2019/03/22(金) 19:06:27.17ID:DJ7JSKt5
>>742
そりゃないよ、かあちゃん
0744デフォルトの名無しさん
垢版 |
2019/03/22(金) 19:28:02.41ID:s6oj+Xdm
>>741
VBAでマルチスレッドは基本的に出来ないと考えるべき。
物凄く不安定だし、Excelのオブジェクト(Rangeとか)を触った途端にExcelが消える。
で、マルチスレッドは出来ないけどマルチプロセスは出来る。

1.プログラムのブックに指定のURLのページの情報を取ってくるプロシージャを作る
2.複数のExcel.Applicationを使って、自分自身のブックを別のExcelから開くメインプロシージャを作り、その中でobjExcel.Runを使って情報を取ってくるプロシージャを動かすようにコードを書く。
3.ブックを保存する。
4.メインプロシージャを動かす

たぶん、こんな感じでできたはず。
0745デフォルトの名無しさん
垢版 |
2019/03/22(金) 19:35:54.55ID:DJ7JSKt5
>>744
ありがとうございます。
しかし、もし50個URLがあれば50個新しくExcel自体を起動しないといけないのですか?
そんなことしたら激重になってしまうように思うのですが。
0751デフォルトの名無しさん
垢版 |
2019/03/22(金) 21:25:13.65ID:uvzdlIQp
なんか勘違いしてるやつがいるけど、VBAがマルチスレッドじゃないことと、IEを複数開くのはまったく別のことだからな

IEはOfficeとはまったく無関係の独立したプロセスだから、いくつでもインスタンス化できるし同時にネットアクセスできる
IEオブジェクトを配列で作っといて、ページの読み込み完了を待たずにどんどん開いてけばいいんだよ
0754デフォルトの名無しさん
垢版 |
2019/03/22(金) 22:13:49.76ID:LAgBLCyu
IEにタブをいくつも開いてもらって、みんな読み込んだところでおもむろに順番に処理すればいいってことだろ。
0756デフォルトの名無しさん
垢版 |
2019/03/22(金) 22:38:21.07ID:DJ7JSKt5
>>750

>>751
その具体的な方法をコードで例示する形で教えていただきたいのでござるよ。

いまだと
Do While readyState < 4
Do Events
Loop
の待ちを50個のURLで1つ1つ順番にやってて
1つのURLを読んでデータ取って閉じる、というのをやるのが社内ネットワークが遅いため(データベースからの読み込みも含まれるからの)1つあたり1分近くかかってる。
だから異常に時間がかかる。
一気に全部同時にやれないかなと。
0759デフォルトの名無しさん
垢版 |
2019/03/22(金) 22:57:51.11ID:HaipTOms
そもそも回線が細いのはプログラムでどうこうできないから上司を説得して諦めてもらうしかない
0760デフォルトの名無しさん
垢版 |
2019/03/23(土) 01:14:24.21ID:BU4e6Kdq
趣味でやってるんじゃなかったら
適当なダウンロードソフト使ったほうが良いんじゃない
0761デフォルトの名無しさん
垢版 |
2019/03/23(土) 12:00:24.62ID:36Js1rz1
動くかどうか試してないけど、こんな感じでいいんじゃない?
もう少し効率を上げるなら、読み込めたページからさっさと処理してもいいし

Sub test()
  pg = 50   ' 同時に開きたいページ数
  Dim ie() As Object
  Dim url() As String
  ReDim ie(pg-1)
  ReDim url(pg-1)
'ここでURL設定
  For i = 0 To pg-1
    Set ie(i) = CreateObject("InternetExplorer.Application")
    ' ie(i).Visible = True  '表示しない
    ie(i).navigate url(i)
  Next
  Do
    flg = True
    For i = 0 To pg-1
      If ie(i).readyState < 4 Then
         flg = False
      End If
    Next
  Loop Until flg  '全ページの読み込み待ち
'ここで読み込んだページを処理
End Sub
0762デフォルトの名無しさん
垢版 |
2019/03/23(土) 15:33:38.79ID:BqJUz3fJ
>>761
ありがとうございます。
試してみます。
最初のFor Nextループがものすごく時間がかかりそうで楽しみです。
あと先日は説明の簡略化のためにシンプルに書いたけど
実は開いたURL内で、ある条件があると、さらにその親URL内のAリンクの子URLも開かないといけない複雑な事情があるのです。
0763デフォルトの名無しさん
垢版 |
2019/03/23(土) 19:47:18.63ID:h2FSWEPH
>>761
Exit For抜けてますよ
フラグも i = pg-1まで行けたときに立たせるだけで十分だと思います

あと、非表示でIEを50立ち上げると中断した時のプロセスの掃除が大変なので、Ajaxで無ければXMLHTTP60を使うのも手かもしれません。
0764デフォルトの名無しさん
垢版 |
2019/03/24(日) 00:51:51.95ID:gZMjxNOF
>>752
まさかIEオブジェクトの読み込み動作がVBAのスレッドで処理されてると思ってるのか?
>>753
終わりじゃないので考慮点はある

コード書こうかと思ったけど、>>761さんが書いてるからまあいいか
読み込み完了の検出とかどうするか悩みどころではある
イベントハンドラの動的設定か、せめてWithEventsが配列にも宣言出来ればなぁ

まあ50も多重化してもオーバーヘッドかかるだけで高速化しない気がするから
数個固定で持たしてイベントハンドリングするのが現実的かもしれん
0765デフォルトの名無しさん
垢版 |
2019/03/24(日) 01:34:57.18ID:Y3S3b5Ai
この場合Do Loopを抜ける条件が全ページの完了だから、Exit Forはあってもなくても結果というかスピードは変わらないね
さっさと抜けたところで、またForループに戻るだけだし

個人的には「pg - 1」が何回も出てくるのが美しくないなあとか、ForとDoの順番を逆にした方がコンパクトになりそうだなあとか
0766デフォルトの名無しさん
垢版 |
2019/03/24(日) 01:38:23.22ID:Y3S3b5Ai
一括処理なら、この方がコンパクト
まあ、ホストの応答速度や、次の処理の内容次第では終わったページからどんどん片付けた方がいいだろうけど
For i = 0 To pg-1
Do
Loop Until ie(i).readyState >= 4
Next
0767デフォルトの名無しさん
垢版 |
2019/03/24(日) 08:29:39.64ID:myNgr9GS
>>765
> 個人的には「pg - 1」が何回も出てくるのが美しくないなあとか
C言語とかに慣れてるんだろう
VBA的には
ReDim ie(1 To pg)
ReDim url(1 To pg)
For i = 1 To pg
だろうね
可能であればieとurlをTypeで纏めてそれを配列にした方が見易い
0769デフォルトの名無しさん
垢版 |
2019/03/24(日) 10:28:46.47ID:3PVCt58k
>>766
それだとサイズのでかいページで待ちが発生する

Do
For i
If ie(i)準備完了 And i.処理フラグFalse then
処理
処理フラグTrue
カウント
End if
Next
カウント=50 exit
Loop
0770デフォルトの名無しさん
垢版 |
2019/03/24(日) 10:33:07.42ID:Mw3X0nZC
>>769
投げてからの待ちだからいいんじゃねえの?
俺はやったことないから知らんが、投げたらあとはIEが並行処理で取ってくるんだろ
で全部取ってから次の処理なら問題ない
でかいページでVBAが待っていても同時に他のページもIEが取って来てるんじゃねえの
だからでかいページで待っていてもそれが終わったら他の軽いページも取り終っていてあとは
ばたばたと進んで終了、と理解している
0771デフォルトの名無しさん
垢版 |
2019/03/24(日) 10:52:55.88ID:Mw3X0nZC
>>769
ああ、すまん。それがわかってる上で待ち時間がもったいない、ということね
>>766もそこは注意書きはしているな
0772デフォルトの名無しさん
垢版 |
2019/03/24(日) 10:56:37.24ID:OZ1kvGmt
IEはマイクロソフトも使うなって言ってるのに
VBAって不便だよね
0773デフォルトの名無しさん
垢版 |
2019/03/24(日) 11:58:25.29ID:yYEn14s6
IE使えなくなったら、どうやってブラウザ制御するの?
UIAutomation面倒くさいかから、
0775デフォルトの名無しさん
垢版 |
2019/03/24(日) 12:34:48.16ID:4ve/ST91
IE使えなくなったらってもう使ってる人なんていない
セキュリティに甘いとこは使えるのか?
0776デフォルトの名無しさん
垢版 |
2019/03/24(日) 13:28:35.85ID:Y3S3b5Ai
ちゃんと動くのか試してみた
たしかにIEが複数開いて、平行処理でページを取ってくるね
VBAのシングルスレッドとか完全に無関係やん
0778デフォルトの名無しさん
垢版 |
2019/03/24(日) 13:36:50.26ID:PYh3zpOu
大昔からあるファイルシステムだって非同期読み書きできる
1000倍遅いネットワークで出来ないはずがないだろうが
0780デフォルトの名無しさん
垢版 |
2019/03/24(日) 14:55:03.02ID:gZMjxNOF
現実的には50並列で全ページ完了待ちするのはどうもなぁ

あと全力でループまわして完了待ちするのも無反応になるんじゃね
とりあえずDoEvents挟もうぜ

>>776
スレッド以前に、IEオブジェクトが別プロセスだから
アウトプロセスのCOM使うのはVBAで並列やる、おそらく安全で簡単な唯一の方法
まあCOM作る方は大変だがな

>>777
OSがサポートしてるだけで、VBAから使えるかどうかとは別の話
VBAで非同期並列やりたければ、基本的にはイベントベースでしかサポートされていない
0781デフォルトの名無しさん
垢版 |
2019/03/24(日) 17:00:18.75ID:cASdygc2
>>776
これ、1つずつ待つ部分がVBAでマルチにしたいって話だったけどCreateObjectで既に別プロセスだから全部投げてから全部の完了を待つので正解なんだよな。

勘違いしてマルチプロセスでやろうとしちゃったよ。
ついでにApplication.Runで出来なくて、迷ってたんだけど、またまた勘違いでApplication.OnTimeが正解だった。
でもOnTimeって戻り値が取れないんだよな。
0782デフォルトの名無しさん
垢版 |
2019/03/24(日) 17:02:38.91ID:cASdygc2
あと、ExcelVBAスレにあるようにInternetExplorer.Applicationじゃなくて別のオブジェクトの方が早いと思うよ。
0785デフォルトの名無しさん
垢版 |
2019/03/24(日) 21:00:07.33ID:IVIO7oct
取りあえず書いてみたんだが、1つずつ待っても速度が変わらん。
テスト用に繋げた所があんまり時間が掛からん所でReadyStateのループに入らんのよ。

取りあえずInternetExplorer.Applicationはやっぱり遅かった。
59個のURLから同じ場所にある特定のデータを取ってくる処理でMSXML2.XMLHttpなら5秒のところIEだと60秒くらい掛かった。
0786デフォルトの名無しさん
垢版 |
2019/03/24(日) 23:42:52.24ID:Y3S3b5Ai
IEを普通にUIを持ったアプリケーションとして開けば、クッキーや画面のレンダリングからアクセス履歴の更新やキャッシュの整理までいろんな処理が走るから、そりゃ実質GETだけのXMLHTTPと比べたら遅くなるのは当たり前と言うか

>>785
画像検索にそれぞれ違うキーワードを設定すれば、それなりに時間がかかるようになるから負荷のテストにはおすすめ
0787デフォルトの名無しさん
垢版 |
2019/03/25(月) 08:15:58.30ID:O3TyiYmg
>>786
そんなことは知ってるが、ここの話で具体的なのがIEだから、いやいや、IEはこんなに遅いですよと注意喚起したんだよ。

まあ、Script関連でIEじゃないと駄目な場合もあるけどね。
0788デフォルトの名無しさん
垢版 |
2019/03/25(月) 21:50:57.49ID:D+uIa6Au
真のエクセラーならieなんか使わずにwebクエリーとか使って何とかするべきだろうが
0789デフォルトの名無しさん
垢版 |
2019/03/25(月) 23:08:06.35ID:DuFQaNpH
getElementByもWebクエリも使ったことあるけど、
Webクエリはどうやって取ってきてるのか謎。
0791デフォルトの名無しさん
垢版 |
2019/03/26(火) 00:39:52.05ID:ke9zWH00
誰もSelenium basic使わんの?
IE使わなくていいしセッション維持とかも楽だぉ?
0792デフォルトの名無しさん
垢版 |
2019/03/26(火) 18:58:02.34ID:ADoE3fhW
readystateが信用ならんのがな
completeになっても完全に読み込めてなくてその後の要素取得処理に失敗とか高確率で起こるし
WinHTTP使うのが確実だと思う
0793デフォルトの名無しさん
垢版 |
2019/03/26(火) 22:23:16.17ID:0P7j5sat
>>791
x だぉ
o だよ
正しい日本語を使いたまえ
0795デフォルトの名無しさん
垢版 |
2019/03/27(水) 00:00:47.48ID:sk2gWEk1
>>794
x 結局Do LoopとOn Error Resume Nextで逃げるしかないっていう。
o 結局Do LoopとOn Error Resume Nextで逃げるしかないっていうことですね。
正しい日本語を使いたまえ
■ このスレッドは過去ログ倉庫に格納されています

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