質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

5回答

2787閲覧

VB.NET ControlAddの処理を軽くしたい

退会済みユーザー

退会済みユーザー

総合スコア0

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2018/08/08 01:21

現在、Controls.Addで明細行を30行程生成しています。

Formを開こうとしてから2秒程止まった後、開かれます。
実際は100行生成したいのですが、これ以上Form表示処理に時間がかかるとユーザー的にも使いにくいものになってしまいます。

現在のコード

For i = 1 to 30
Create()
Next

Private Sub Create

Dim Label As New Label
(ステータス指定処理)
Controls.Add(Label)
....

End Sub

軽くする方法、または別の方法をご教授頂ければ嬉しいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

もう質問者が退会していますが・・・
スピードアップのテクニックとして、1行分のレイアウトが同一なら、行ごとユーザーコントロールにするとControls.addする際の処理時間がバラバラで処理するより短くなりますよ。


ここからは完全に余談なんですが、コンストラクタでControls.addする時間とLoadイベント内でaddする時間を比較すると、確かにコンストラクタで実行したほうが何倍も速いです。
しかし、実際にフォームをNew→showする時間を比較すると、コンストラクタ版は体感できるほど早くありません。コンストラクタ版のほうがほんのちょっと早いくらい。

Windows フォームのイベントの順序というドキュメントがMicrosoftのサイトにありまして、ここに書かれているイベントにそれぞれStopWatchを仕掛けて計測してみると、Loadイベント版は当然Loadに最も時間がかかっていますが、コンストラクタ版はLoad版のLoadと同じくらいの時間がBindingContextChangedでかかっていました。
なので、Formの初期化で真に時間がかかる処理はBindingContextの初期設定なんじゃないかと考えます。

なお、本当にFormのロード処理でユーザーを待たせたくなかったら、あらかじめhidden状態でフォームを初期化しておいて、実際にユーザーが開いた際にvisible=trueするのが体感もっとも早いと思います。そういう話はナシですか…?

投稿2018/08/08 14:49

hope_mucci

総合スコア4447

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

作成するコントロールを配列にしてControls.AddRangeにて追加すれば
多少は改善するかと思います。

下記コードにて検証しましたところ
Controls.Add・・・・・約1500ms
Controls.AddRange・・・約550ms
となりました。

ただ、テストコードでラベルを1000個生成していますが、遅くて1500msとなっています。
他の部分で遅くなっている可能性もありますので、どこが遅いか検証してください。

VB.NET

1 Private labels(999) As Label 2 3 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 4 5 Dim sw As New Stopwatch 6 Me.AutoScroll = True 7 8 sw.Start() 9 For i = 0 To 999 10 Create(i) 11 Next 12 sw.Stop() 13 Trace.WriteLine(sw.ElapsedMilliseconds) 14 15 16 sw.Restart() 17 For i = 0 To 999 18 Create2(i) 19 Next 20 Controls.AddRange(labels) 21 sw.Stop() 22 Trace.WriteLine(sw.ElapsedMilliseconds) 23 End Sub 24 25 Private Sub Create(index As Integer) 26 27 Dim Label As New Label 28 29 Label.Text = String.Format("ラベル{0:000}", index) 30 Label.Top = 30 * (index \ 10) 31 Label.Left = 100 * (index Mod 10) 32 Label.Visible = True 33 34 Controls.Add(Label) 35 End Sub 36 37 Private Sub Create2(index As Integer) 38 39 Dim Label As New Label 40 41 Label.Text = String.Format("ラベル{0:000}", index) 42 Label.Top = 30 * (index \ 10) 43 Label.Left = 100 * (index Mod 10) 44 Label.Visible = True 45 46 labels(index) = Label 47 End Sub 48

追記

コメントから読み取れたように、1行30コントロール(Labelを15個、TextBoxを15個)とし、100行を
コントロール1つづつAddしたところ、約2200msとなりました。
これを、1行分をUserControlとして作成し、UserControlを100個生成するようにしたところ、約1100msとなりました。
また、SuspendLayout、ResumeLayoutを使用すると、多少速くなる可能性があるかと思います。

投稿2018/08/08 01:44

編集2018/08/08 04:35
YAmaGNZ

総合スコア10266

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/08/08 02:10

ありがとうございます! Rangeをつけるだけで3倍もはやくなるのは目から鱗です。 こちらで一旦検証してみますが、他にも軽くする知識をご存知でしたらご教授願いたいです。 宜しくお願い致します。
YAmaGNZ

2018/08/08 02:19

違いが分かりやすいようにフォームのAutoScrollをTrueにしていますが、Falseにした場合、速度が全然違います。 まずは、ご自身のプログラムのどこで時間がかかっているか明確にしてください。
guest

0

ラベルを 100 個作るということは、表示しきれないのでスクロール領域の計算が繰り返されている可能性があります。

Control.SuspendLayout メソッド () を使うと改善するかもしれません。

また、ラベルではなく DataGridView や ListView などの使用を検討してください。

投稿2018/08/08 04:29

Zuishin

総合スコア28662

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

解決方法は自分でもっと考える。

YAmaGNZさん以外まともな解答じゃなかったです。

投稿2018/08/08 07:02

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2018/08/08 07:39 編集

どうぞ頑張ってください。
guest

0

フォームデザイナでLabelを100個並べておけばいいんじゃ?
それだと時間はかからないでしょ

投稿2018/08/08 03:05

y_waiwai

総合スコア87784

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/08/08 03:07

1行に使うオブジェクトはLabelだけじゃないので厳しいです・・・。 すみません。
y_waiwai

2018/08/08 03:08

なら使う可能性のあるコントロールを全部並べておけばいい。 必要のあるものだけ Visible=true すればいいだけのはなし
YAmaGNZ

2018/08/08 03:17

本当にContols.Addにて時間がかかっているのであれば、デザイナで並べても速度はあまり変わらないと思います。デザイナで並べてもInitializeComponent内でControls.Addしているわけですし。 正直今回の場合は他の部分で時間がかかっているのだと思っています。
y_waiwai

2018/08/08 03:31

起動が遅くなるだけならやりようはあるかと。 少なくとも、フォームを表示しようとしてそこで時間がかかる事態は避けることができる。 >正直今回の場合は他の部分で時間がかかっているのだと思っています。 これには同意。
退会済みユーザー

退会済みユーザー

2018/08/08 03:55

y_waiwaiさん 質問の主旨と違う回答をされるのであれば別の質問へお願い致します。 InitializeComponentでControlsAddが使われてる事はご存知ではなかったんでしょうか。 それと、オブジェクトネームを手作業で1000個以上行うのは非現実的なのはわかりませんか。 とにかく書き込んでポイントをゲットしたいというのであれば申し訳ございませんが、他でお願い致します。 YAmaGNZさん コメントありがとうございます。 >正直今回の場合は他の部分で時間がかかっているのだと思っています。 こちらですが、新規プロジェクトでControls.Addのみを行ってテストしているのでそれはないかと思います。 ただオブジェクト数でいうと1行30オブジェクト(ラベル・テキストボックスがほとんど) を30行なので実質900オブジェクトくらい配置で500msです。 これを100行にしたいが1500msとなるとユーザー目線使い勝手の悪いものになってしまうと思い、質問させていただきました。 なにかご存知でしたらご教授願いたいです。 宜しくお願い致します。
y_waiwai

2018/08/08 04:03

まあ、この回答を無視したいならどうぞそうしてください。わざわざ言及する必要はありません。 ちなみに、いままでコントロールを数百個乗せたフォームを数枚乗せたコードを書いたことがありますが、時間で問題になった記憶はありません。 それではごきげんよう
YAmaGNZ

2018/08/08 04:06

いえ、y_waiwaiさんが言っていることはフォームをNewした時にコントロールを追加することになるので、Loadイベントでフォームが表示されるタイミングとずらすことになる。 だから、フォームを表示する前に準備ができることになり、例えばボタンを押した時にフォームを表示するといった処理の場合に待たせることがなくなるということです。
YAmaGNZ

2018/08/08 05:02

すみません。私の - 本当にContols.Addにて時間がかかっているのであれば、デザイナで並べても速度はあまり変わらないと思います。デザイナで並べてもInitializeComponent内でControls.Addしているわけですし。 - というのは間違いですね。 コンストラクタ内での生成であれば、表示されていない分高速にコントロールの追加が行われます。
退会済みユーザー

退会済みユーザー

2018/08/08 06:32

InitializeComponent内はSuspendLayoutを使用してControls.Addしていますよね。 "表示されていない分高速にコントロールの追加が行われます。" この文の意味がわからないのですが、コードにして教えていただけますか?
yukihisa

2018/08/08 06:46

コードに書かない(デザイナで置いておく)から早いよって言ってるのでコードで説明するのは無理かと。。。
退会済みユーザー

退会済みユーザー

2018/08/08 07:00

いや、デザイナで置く = コードが無いってそんなバカな話ないでしょう。 デザイナというのはUIでわかりやすく配置出来るようにしたものであって、全てコードですが。
y_waiwai

2018/08/08 07:05

だめだこりゃww
退会済みユーザー

退会済みユーザー

2018/08/08 07:07

>それではごきげんよう 気になって来ちゃってますね・・・あらら・・・
退会済みユーザー

退会済みユーザー

2018/08/08 07:09

調べてみたら、MSDNにもしっかり記されてましたが >だめだこりゃww って自分の頭のこと言ってますか?
y_waiwai

2018/08/08 07:10

ああ、スマン、あまりにひどいもんだったんで笑いを我慢できなくてwww うんうん、がんばってください。
y_waiwai

2018/08/08 07:12

んで、この茶番を続けるならぜひ別の回答を立ててやってくだされ。通知が来てうざいw まあ、嗤われるのが趣味なら強制はしないけどw
yukihisa

2018/08/08 07:12

申し訳ない、初心者かと思いコード≒処理という意味で使っておりました。 ただ、そこまで理解しているならなおさらコードで説明できるかどうか分かりそうな気がします。 つまり、コンストラクタ内での生成速度と処理内での生成速度の違いをコードで説明せよ、ということを仰っているのですよね? 描画処理をする必要がない分コントロールの追加の速度が速く、その後表示時にvisibleの設定をするだけでいいので、そっちのほうが早いよと言っているのです。 極端に言えばエクセルの書類作るのにテンプレートあったほうが早いよねと言っているのと同じです。それはコードで説明できるものではないです。 どのような処理に何msかかるかというレベルまで掘り下げないとコードでの説明は不可能だと思いますよ?
退会済みユーザー

退会済みユーザー

2018/08/08 07:12

まだここのスレッドに来ていることに対して言ってるんですが・・・日本語も読めませんか・・w 揚げ足を取ったふうに見せてるんでしょうけど具体的なことがなに一つ書けてなく滑稽ですねw 一日中しょうもないコメント返信ごっこをこれからも頑張って続けてくださいwではw
yukihisa

2018/08/08 07:13

y_waiwai 様 お目汚し申し訳ない。。。 別の回答を立てるのも微妙なのでこれで終わりにします、すいません。
y_waiwai

2018/08/08 07:17

オレの回答のコメントなんですがwww 別に他の回答にまで乗り込もう友思わないんで、オレを目にするのが嫌ならぜひ他所に行ってくださいw せーぜーがんばってくださいねー
y_waiwai

2018/08/08 07:18

まー、ほっときましょうや。もうまともに話聞く態度でもないでしょ>yukihisa
fana

2018/08/08 07:22

とりあえず,現在どこぞでやっている激遅なコントロール追加作業処理のコードを InitializeComponentをコールしている直後(コンストラクタ内)に移したら速度がどう変化するのか試してみればいいのでは?
YAmaGNZ

2018/08/08 07:26

とりあえず最後に コンストラクタ内でのコントロールの追加が行われた場合、SuspendLayoutしなくともCreateControlイベントを発生させるコードやPaintなどのコードが動作しません。 Form.Loadにてコントロールが表示されるとそのあたりのコードが動きます。 このようにコンストラクタ内で表示されていない状態と親が表示される(されている)状態では動作が違いますので、処理時間が異なる話になります。 このあたりの検証はコントロールを継承してログをしこんでみてください。
yukihisa

2018/08/08 07:43

y_waiwai 様 夏休みだからか自分で考えることを放棄している人が多いので仕方ないですね。。。 YAmaGNZ 様 勉強になります。 ただ、そもそもとして条件でコントロールを使い分けたり、増減させたりではなく、 今回のような明細を表示するというのならDataGridViewの方が見やすい気がします。。。
退会済みユーザー

退会済みユーザー

2018/08/08 07:56

yukihisaって人システム開発した経験が無いまたはめちゃくちゃ少ないんでしょうね。 DataGridViewを実際に伝票入力として使うなんてそんな不便な事はないんですが。 もうネット上で頑張って博識な自分を演じる必要は無いですよ、すぐ露呈してしまいますから。 他の回答見てみましたが、的外れまくってますしね。 夏休みの間にせいぜいお勉強頑張ってくだはれ。
退会済みユーザー

退会済みユーザー

2018/08/08 07:57

因みに社会人の夏休みは12日の週なので、聞いたときは唖然としました。 自分から自分が学生だと墓穴をほってますね。
y_waiwai

2018/08/08 08:01

他人を煽るしか能が無いクズか。。 どーしよーもないねえ
退会済みユーザー

退会済みユーザー

2018/08/08 08:15

自分が煽るクズと言われても別になんの問題もないですが。 もっとも、y_waiwaiに庇う言葉をもらえてないyukihisaをみれた事が至福ですね。 ネットは子供がやるものじゃないぞw やりたいならままと一緒にやりなw
yukihisa

2018/08/08 08:16

y_waiwai 様 そうですねぇ、まさかベストアンサー率50%以上で的外れまくりと言われるとは、 理想は高く持てと言いますが凄い厳しいですね 苦笑 伝票入力にわざわざLabel大量に動的に作成してどうするんだろう。。。? それこそメンテナンス性とか考えたら静的に作るべきだと思うんだけどなぁ、不思議。 デザイナでテキトーに作ってテキストエディタなりにはっつけてリネームしたらそんなに時間かからないのに。。。 ちなみに一人親方の僕には夏休みなんて1日もないですよorz 休んだらその分収入が減るのはきついですねー
y_waiwai

2018/08/08 08:20

ああ、逃げてしまわれたw
yukihisa

2018/08/08 09:25 編集

ありゃ、一人で顔真っ赤にして消えてしまわれた。。。w 今回の問題点は明細行を作成する≠出力画面だったことですね。 入力用画面で全て表示する前提で処理速度気にするなら静的に作成する一択だわw
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問