#環境
OS:windows10
ラップトップのパソコンを使用しています。
購入時期:去年
#やっていること
今現在、やっていることは、
設計図のデータ(.CSV)をexcelのVBAで、
必要な情報のみを抽出するプログラムを書いています。
ただ、処理するデータの量がテストデータ(運用を想定したデータ量)で
60000件あります。
それを処理しようとすると、
「応答なし」になってしまい、うまく最後まで処理ができません。
###プログラム
量が多く、一応コンパイルは成功しているはずなので、
軽く目を通す程度にすることを推奨します。
一番最初に実行するのは、標準モジュール側の、「寸法書作成」というサブルーチンです。
その後、ユーザーフォームを起動して、
コマンドボタンを、クリックすると必要な情報が、
テキストボックスに記入されているかを「エラーチェックサブルーチン」で、
確認したのち、各変数に代入後、標準モジュールに戻ります。
標準モジュールでは、必要な情報のみをえらんで、
別のシートに出力するというものです。
lang
1UserForm側-------------------------------------------------------- 2Option Explicit 3Public e_name, アルファベット As Variant 4------------------------------------------------------------------- 5Private Sub CommandButton1_Click() 6 7While sw = 0 8 Call エラーチェック 9Wend 10 11'各座標を取得する 12左上座標x = TextBox1.Text: 左上座標y = TextBox2.Text 13左下座標x = TextBox3.Text: 左下座標y = TextBox4.Text 14右上座標x = TextBox5.Text: 右上座標y = TextBox6.Text 15右下座標x = TextBox7.Text: 右下座標y = TextBox8.Text 16 17'入力エラー時にウィンドウを閉じなくする。&寸法の処理を実行しないよう制御 18If e_name = "none" Then 19 Unload UserForm1 20End If 21 22 23 24 25End Sub 26------------------------------------------------------------------ 27Private Sub CommandButton2_Click() 28'クリアボタン 29TextBox1.Text = "" 30TextBox2.Text = "" 31TextBox3.Text = "" 32TextBox4.Text = "" 33TextBox5.Text = "" 34TextBox6.Text = "" 35TextBox7.Text = "" 36TextBox8.Text = "" 37End Sub 38------------------------------------------------------------------- 39Private Sub CommandButton3_Click() 40'終了ボタン 41End 42End Sub 43------------------------------------------------------------------- 44Private Sub エラーチェック() 45On Error GoTo Error 46 47Dim a As Byte 48'エラーの種類を区別する変数 49e_name = "none" 50'入力された文字列を探索する文字列(アルファベット大小32文字) 51アルファベット = "abcdefghijklmnpoqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 52 53 54For a = 0 To 31 55'空白の探索 56 If TextBox1.Text = "" Or _ 57 TextBox2.Text = "" Or _ 58 TextBox3.Text = "" Or _ 59 TextBox4.Text = "" Or _ 60 TextBox5.Text = "" Or _ 61 TextBox6.Text = "" Or _ 62 TextBox7.Text = "" Or _ 63 TextBox8.Text = "" Then 64 65 e_name = "blank" 66 GoTo Error 67 68 End If 69'文字列が混入していないか調べる 70 If InStr(TextBox1.Text, Mid(アルファベット, a + 1, 1)) <> 0 Or _ 71 InStr(TextBox2.Text, Mid(アルファベット, a + 1, 1)) <> 0 Or _ 72 InStr(TextBox3.Text, Mid(アルファベット, a + 1, 1)) <> 0 Or _ 73 InStr(TextBox4.Text, Mid(アルファベット, a + 1, 1)) <> 0 Or _ 74 InStr(TextBox5.Text, Mid(アルファベット, a + 1, 1)) <> 0 Or _ 75 InStr(TextBox6.Text, Mid(アルファベット, a + 1, 1)) <> 0 Or _ 76 InStr(TextBox7.Text, Mid(アルファベット, a + 1, 1)) <> 0 Or _ 77 InStr(TextBox8.Text, Mid(アルファベット, a + 1, 1)) <> 0 Then 78 e_name = "string" 79 GoTo Error 80 81 End If 82'コンマがちゃんと入っているか確認 83 If TextBox1.Text = Int(TextBox1.Text) Or _ 84 TextBox2.Text = Int(TextBox2.Text) Or _ 85 TextBox3.Text = Int(TextBox3.Text) Or _ 86 TextBox4.Text = Int(TextBox4.Text) Or _ 87 TextBox5.Text = Int(TextBox5.Text) Or _ 88 TextBox6.Text = Int(TextBox6.Text) Or _ 89 TextBox7.Text = Int(TextBox7.Text) Or _ 90 TextBox8.Text = Int(TextBox8.Text) Then 91 92' If InStr(TextBox1.Text, ".") <> 1 Or _ 93 InStr(TextBox2.Text, ".") <> 1 Or _ 94 InStr(TextBox3.Text, ".") <> 1 Or _ 95 InStr(TextBox4.Text, ".") <> 1 Or _ 96 InStr(TextBox5.Text, ".") <> 1 Or _ 97 InStr(TextBox6.Text, ".") <> 1 Or _ 98 InStr(TextBox7.Text, ".") <> 1 Or _ 99 InStr(TextBox8.Text, ".") <> 1 Then 100 e_name = "notcon" 101 GoTo Error 102 103 End If 104Next a 105 106 107 108 109'例外処理 110 111Error: 112Select Case e_name 113 Case "string" 114 MsgBox ("余分な文字が混入しています。") 115 116 Case "blank" 117 MsgBox ("空白の欄が存在します。すべて記入してください。") 118 119 Case "notcon" 120 MsgBox ("コンマが抜けているか、二つ以上存在します。") 121 122 Case "none" 123 sw = 1 124 125End Select 126 127End Sub 128------------------------------------------------------------------- 129
lang
1標準モジュール側----------------------------------------------------- 2 3Option Explicit 4 5Public sn, sw As Byte 6Public 右上座標x, 右下座標x, 左上座標x, 左下座標x As Variant 7Public 右上座標y, 右下座標y, 左上座標y, 左下座標y As Variant 8Public 始点x, 始点y, 差分x As Integer 9Public 終点x, 終点y, 差分y As Integer 10 11------------------------------------------------------------------- 12Public Sub 寸法書作成() 13 14 15 16sw = 0 17UserForm1.Show 18 19 20'先に範囲指定 21Call 範囲指定 22 23 24 25 26 27'抽出する項目の設定 28Dim meji配列 As Variant 29meji配列 = Array("●09石仕上面", "●08石裏", "●08石仕上(平面・原寸石裏)", "●11石目地(目地有)", "●18石番号") 30 31'行変数の初期設定 32Dim row As Integer 33row = 2 34 35'シート作成 36Call シート作成 37 38 39'セルが空白になるまで探索する 40Dim meji As Variant 41 42While Worksheets(1).Cells(20, row) <> "" '20列目は「画層」 43 For Each meji In meji配列 44 If Worksheets(1).Cells(20, row) = meji Then 45 46 '指定した範囲に存在しているか調べる 47 If Cells(131, row) >= 始点x And Cells(132, row) >= 始点y And _ 48 Cells(134, row) <= 終点x And Cells(135, row) <= 終点y Then 49 With Worksheets(sn + 1) 50 .Cells(1, 2) = Worksheets(1).Cells(20, row) 51 .Cells(2, 2) = Worksheets(1).Cells(131, row) 52 .Cells(3, 2) = Worksheets(1).Cells(132, row) 53 .Cells(4, 2) = Worksheets(1).Cells(134, row) 54 .Cells(5, 2) = Worksheets(1).Cells(135, row) 55 End With 56 End If 57 End If 58 Next meji 59Wend 60 61 62 63 64 65End Sub 66------------------------------------------------------------------- 67 68Sub 範囲指定() 69'r = right(右) 70'l = left(左) 71'o = over(上) 72'u = under(下) 73'x = x軸 74'y = y軸 75 76Dim rox, rux, lox, lux As Integer 77Dim roy, ruy, loy, luy As Integer 78 79'各座標を千の位未満を切り捨てる 80lox = WorksheetFunction.Round(左上座標x / 1000, "0"): loy = WorksheetFunction.Round(左上座標y / 1000, "0") 81lux = WorksheetFunction.Round(左下座標x / 1000, "0"): luy = WorksheetFunction.Round(左下座標y / 1000, "0") 82rox = WorksheetFunction.Round(右上座標x / 1000, "0"): roy = WorksheetFunction.Round(右上座標y / 1000, "0") 83rux = WorksheetFunction.Round(右下座標y / 1000, "0"): ruy = WorksheetFunction.Round(右下座標y / 1000, "0") 84 85'座標の範囲を求める 86'd = difference(差分) 87Dim oxd, uxd, lyd, ryd As Integer 88 89'上底側のx軸の差分 = 右上座標x - 左上座標x 90oxd = rox - lox 91 92'下底側のx軸の差分 = 右下座標x - 左下座標x 93uxd = rux - lux 94 95'左辺側のy軸の差分 = 左上座標y - 左下座標y 96lyd = loy - luy 97 98'右辺側のy軸の差分 = 右上座標y - 右下座標y 99ryd = roy - ruy 100 101'x軸の始点と終点と差分の決定 102If oxd = uxd Then 103 始点x = lox 104 終点x = rox 105 差分x = oxd 106Else 107 If oxd > uxd Then 108 始点x = lox 109 終点x = rox 110 差分x = oxd 111 Else 112 If oxd < uxd Then 113 始点x = lux 114 終点x = rux 115 差分x = uxd 116 End If 117 End If 118End If 119 120'y軸の始点と終点と差分の決定 121If lyd = ryd Then 122 始点y = luy 123 終点y = loy 124 差分y = lyd 125Else 126 If lyd > ryd Then 127 始点y = luy 128 終点y = loy 129 差分y = lyd 130 Else 131 If lyd < ryd Then 132 始点y = ruy 133 終点y = roy 134 差分y = ryd 135 End If 136 End If 137End If 138 139 140 141End Sub 142------------------------------------------------------------------- 143Sub シート作成() 144sn = Worksheets.Count 145Worksheets().Add After:=Worksheets(sn) 146With Worksheets(sn + 1) 147 .Cells(1, 1) = "画層" 148 .Cells(1, 2) = "始点x" 149 .Cells(1, 3) = "始点y" 150 .Cells(1, 4) = "終点x" 151 .Cells(1, 5) = "終点y" 152End With 153 154End Sub 155-------------------------------------------------------------------
上記がプログラムの一覧です。
#自分の考えとしては...
今私が考えている方法では、
ミニバッチ化してしまえば応答なしにはならないのではないか、
と考えています。
ただ、それでもうまくいかないとも考えています。
なので、時間は多少かかってもいいので、
応答なしにならずに処理する方法を知りたいです。
どなたか、わかる方いらしゃれば教えてください。

回答8件
あなたの回答
tips
プレビュー