• 締切済み

VBAに関して、selectを使わない方法

現在、全国の都道府県の市町村別である数値を測るプログラムをつくっています。 現在のプログラムはselectを使い、市町村を選択した(人口や県庁所在地等で大まかにわけた)後、47都道府県を選択し計算するようになっています。下にプログラム例を張ります。ageと面積は入力画面(ユーザーフォームにて作成)にて入力する値となります。 select city case 札幌  age1*○○+age2*△△+age3*◆◆ case 町村  age1*●●+age2*▲▲+age3*□□ ・ ・ ・ end select ・ ・ ・ select area case 北海道  面積1*☆☆+面積2*★★ case 青森  面積1*▼▼+面積2*▽▽ ・ ・ ・ end select といった感じです。selectを使っているため非常に量が多いので、selectを使わないようにしたいのです。ループ文を使おうと考えたのですが、かける数値(★や□)も違い、計算する箇所がふたつあるためどのようにすればよいか分かりません。 つかったとしてもプロシージャが大きくなりすぎないようにしたいのですが、ifをつかって別のモジュールで市町村だけ計算させ、さらにifを使い別のモジュールで都道府県だけで計算させ、出力の時に結果だけ抽出することなど可能でしょうか?他に簡単な方法とかありますか? 皆さんの力をお貸しください。 回答よろしくお願いします。

みんなの回答

  • ap_2
  • ベストアンサー率64% (70/109)
回答No.4

ANo.3の熱意(?)にちょっと刺激されて、再回答。 式共通で係数が違うだけなら、  ・フォームはユーザ操作関連処理のみ  ・データシート(係数リスト)  ・シートから係数を取得する関数  ・値や係数から算出する関数 で、シンプルに切り分けできるかと。 係数取得と算出で10行程度なので、1つの関数にしちゃっていいです。 データシートは、県と市町村で2つに分けて、1行1データ。地名列を検索(Find)して、その行の情報を取得する形で使います。必要に応じて、パラメータ以外の情報(市町村データはせめて県名を)も持たせると管理しやすいです。 あと、ソースからのパラメータ抽出は、「秀丸エディタ」とか使えば、正規表現で置き換え1発かも。 お役所のデータは「地名:値」多いから、何かと使えるかと。がんばって。

  • tsubuyuki
  • ベストアンサー率45% (699/1545)
回答No.3

・・・と思ったら、 これ、都道府県・市町村別に作るつもりですか? 正直、無駄です。 先ほど「無駄な処理を省いて・・」とレスしましたが、 何となくすごく無駄です。 マクロに入る前にもう少しシート内で処理できる部分を考えませんか? 例えば、都道府県・市町村にコードを設けて、ある程度の集計区分に分けたコードを付加して、 それを基に計算係数を別表に用意しておいて、 VLOOKUPなどで係数を引っ張って、予備計算しておいて・・・とか、 見た感じでは出来るような気がしますよ?    1:政令指定都市:係数1.5    2:その他市:係数1    3:町村:係数0.5 などと係数表を持って、    札幌(=政令指定都市):1    小樽(=その他市):2    厚岸(=町村):3 とコードを付けてやれば、VLOOKUPで係数を引っ張ってこれますよね? コレを基にしてやれば、シート内で計算できるはずです。 少なくとも、都市別にCaseを作る必要は無いはずです。 これだけでもモジュールは随分スリムに出来ます。 コレに拘らないにしても、何か手段があるはずです。 なんとか探してみませんか?

  • ap_2
  • ベストアンサー率64% (70/109)
回答No.2

パラメータは配列で持った方がよさそうです。 せっかくのExcelなので、パラメータリストをシートに持って、地名とマッチした行のパラメータを取ってくるように作るのもアリかと。シートは、非表示にもできます。

  • masatsan
  • ベストアンサー率15% (179/1159)
回答No.1

配列にするくらいですかね。

関連するQ&A

  • VBA: Select Caseを短くしたい

    Excel2003 の VBA でクラスモジュールを作成しています。 Select Case文で Caseが多い場合にコードを短くするテクニックがありませんか。 Select Case i   Case 1     str = "momo"   Case 2     str = "sakura"       ・       ・       ・   Case 100     str = "tsubaki" End Select のようなコードです。 配列に入れることも考えましたが、 str(1) = "momo" str(2) = "sakura"      ・      ・      ・ str(100) = "tsubaki" となって、コードを短くする効果は僅かです。 クラスモジュールなので、ワークシートにデータを入れておくテクニックは使えません。 また、外部ファイル(*.txt など)も管理の面から使いたくありません。 クラスモジュール内だけで完結させるテクニックがないでしょうか。

  • エクセルVBAの Select Case構文

    Range("A1")に数式が入っています。 Select Caseで エラーだった場合 計算結果が正数だった場合 計算結果が負数だった場合 計算結果が"特定の文字"だったばあい その他 で分岐したいのですが、どのように記述すればよいのでしょうか? 以下、わたしの失敗例です。AAAでもプラスと出てしまいます。エラー値の判別がわかりません。 Sub TEST() Select Case Cells(1, 1) Case Is > 1: MsgBox "プラス" Case Is < 0: MsgBox "マイナス!" Case "AAA": MsgBox "AAA" Case Else: MsgBox "やり直し" End Select End Sub

  • Select Caseで条件が複数の場合

    ifではなくSelect Case で表現するにはどうすればいいでしょうか? Sub Macro1() ひらがな = "い" カタカナ = "イ" Select Case ひらがな Case "あ" Select Case カタカナ Case "ア" MsgBox "ひらがな = ""あ""カタカナ = ""ア""です" End Select End Select Select Case ひらがな Case "い" Select Case カタカナ Case "イ" MsgBox "ひらがな = ""い""カタカナ = ""イ""です" End Select End Select End Sub この場合あ~おまでの条件を設定したい場合どのように書けばいいのでしょうか? またひらがな = "あ"、カタカナ = "イ"の場合はスルーしたいです。 なにか効率のいい方法はありますでしょうか? IFの方が書き方としては正しいのでしょうか? よろしくお願い致します。

  • Excel VBA ENTERで特定のセルへ移動

    他の質問でみつけたコードですが どなたか以下のコードの内容を説明(翻訳)していただけないでしょうか よろしくお願いします。 '<標準モジュール> Private Sub ReturnDirectrion2SelectCell()  If ActiveCell.Address(0, 0) Like "A2" Then   Range("B5").Select  Else   'Original ReturnDirection の再現   On Error Resume Next   Select Case Application.MoveAfterReturnDirection   Case xlDown     ActiveCell.Offset(1).Select   Case xlToRight     ActiveCell.Offset(, 1).Select   Case xlToLeft     ActiveCell.Offset(, -1).Select   Case xlUp     ActiveCell.Offset(-1).Select   End Select  End If End Sub Sub SetKeys()   '設定用   Application.OnKey "~", "ReturnDirectrion2SelectCell"   Application.OnKey "{Enter}", "ReturnDirectrion2SelectCell" End Sub Sub SetOffKeys()  '解除用  Application.OnKey "~"  Application.OnKey "{Enter}" End Sub '----------------------------------------- 自動設定が必要な場合は、以下のコードを加えてください。 '----------------------------------------- '<標準モジュール> Sub Auto_Open()  Call SetKeys End If Sub Auto_Close()  Call SetOffKeys End If '----------------------------------------- 以上です。よろしくお願いします。

  • VBAに関して、プロシージャが大きく悩んでいます。

    回答よろしくおねがいします。 現在、全国の各都道府県のある数値を測るプログラムを改良しています。 入力画面に人口等の数値を入力すれば自動的に計算が行われるプログラムなんですが、現在改良する際にプログラムが大きくなりすぎて悩んでいます。 入力画面はユーザーフォームで作成してあるのですが、改良を行うとプロシージャが大きすぎますと警告が出ます。 そこでprivate subを用いて3つにプログラムを分け、最後にcallでそれらを選択したが計算されませんでした。 元々あったプログラム(改良前のものなので普通ならばできるはず)をprivate sub1、private sub2、private sub3として同じユーザーフォーム内に3つに分割しました。それぞれきちんと定義はしてあります。最後にcallで3つを呼び出したのですが、何一つ計算されませんでした。エラーが出るわけでもありません。入力画面にて入力された数値はひとつのprivate subにのみ有効なんですか? 現在この問題に対して考えているのは、本筋(ユーザーフォーム内のプログラム)を定義のみとし、ifやcallを使い別のモジュールで計算させ結果だけ本筋に戻すことを考えています。こういったことは可能でしょうか? 可能な場合は具体的にどういうプログラムになるのか教えていただければありがたいです。 よろしくお願いいたします。

  • ExcelのVBAで教えてください。

    Private Sub Worksheet_Changeについて教えて下さい。 まず初歩的なご質問ですが、Private Sub Worksheet_Changeを1つのシートモジュールに1個以上組むことは可能なのでしょうか? 例えばネットで以下のようにsheet1に Private Sub Worksheet_Change Private Sub Worksheet_Change_1 _1を付けてるのを見たことがあったので試してみましたが動作しませんでした。 今回行いたいのは1つが、指定したセルが変更されると次の指定セルに移動する。 以下がマクロです。 Private Sub Worksheet_Change(ByVal Target As Excel.Range) Select Case Target.Address(0, 0) Case "E14" [E15].Select Case "E15" [E26].Select Case "E26" [E22].Select Case "E22" [E25].Select Case "E25" [E29].Select Case "E29" [E20].Select Case "E20" [E21].Select Case "E21" [E16].Select Case "E16" [E17].Select Case "E17" [E27].Select Case "E27" [E23].Select Case "E23" [E24].Select Case "E24" [E28].Select Case "E28" [E18].Select Case "E18" [E19].Select End Select End Sub もう一つが、あるセルに数値をいれると他のブックのシートからそのシートの指定した行のセルの 数値を読み込んできて、元のブックのシートに数値を書き込むといったもです。 以下がマクロです。 Private Sub Worksheet_Change_1(ByVal Target As Excel.Range) Dim w As Workbook Dim c As Range On Error Resume Next Set xCur = Selection If Application.Intersect(Target, Range("F3")) Is Nothing Then Exit Sub If Range("F3") = "" Then Exit Sub Application.ScreenUpdating = False '転記元のブックを開いて逆順で検索する Set w = Workbooks.Open("V:\新3係(FIA・iPot)\(2)新4係(iPot)\ipot進捗\履歴管理\(9)KBB39360 X8 imm1.35 G1履歴、本体履歴 .xls") Set c = w.Worksheets("対物").Range("B:B").Find(what:=Range("F3").Value, LookIn:=xlValues, lookat:=xlPart, searchdirection:=xlPrevious) '見つけた(一番下の)セルを基準に転記する If Not c Is Nothing Then Range("F4").Value = c.Offset(0, 1).Value End If w.Close False Application.ScreenUpdating = True End Sub ともに1つずつなら問題なく動作するのですが、2個のマクロを組むと片方しか動作しません。 多分ものすごく初歩的な事だとは思いますが、御指導の程宜しくお願いします。

  • Accessのフォームのオープンのコマンド。

    テーブル1 ・名前 ・誕生日 ・年齢 フォーム1 ・名前 ・誕生日 ・年齢 ・コマンドボタン コマンドボタンのコード Private Sub コマンド6_Click() Age_Keisan End Sub 関数Age_Keisanのコード Private Sub Age_Keisan() Dim Age As Integer Dim Birth_Y As Integer Dim Birth_M As Integer Dim Birth_D As Integer Dim Now_Y As Integer Dim Now_M As Integer Dim Now_D As Integer Birth_Y = Left([誕生日], 4) Birth_M = Right(Left([誕生日], 7), 2) Birth_D = Right([誕生日], 2) Now_Y = Left(Date, 4) Now_M = Right(Left(Date, 7), 2) Now_D = Right(Date, 2) Select Case Birth_M Case Is < Now_M Age = Now_Y - Birth_Y Me![年齢] = Age Case Is > Now_M Age = Now_Y - Birth_Y - 1 Me![年齢] = Age Case Is = Now_M Select Case Birth_D Case Is <= Now_D Age = Now_Y - Birth_Y Me![年齢] = Age Case Is > Now_D Age = Now_Y - Birth_Y - 1 Me![年齢] = Age End Select End Select End Sub となっています。 これですと、年齢を入れて、ボタンを押さないと誕生日が過ぎた場合、年齢が増えていきません。 クエリーを使用してフォームをつくればよかったのですが、テーブルから直接フォームを作成しているので 計算もできません。 できればフォームのオープンコマンドに上記のボタンと同じような機能を入れたいのですが、 どのようにすればいいのでしょうか?

  • 集計を求めるSQL文について

    こんにちは。 はじめまして、MMM-SRVと申します。 初めて投稿させて頂きます。 宜しくお願い致します。 MS Access2000をデータベースとしてASPでプログラムを組んでおります。 その中でどうしてもわからないので教えて下さい。 create table t1 ( age varchar(30), -- 年代 sex varchar(30), -- 性別(男'0'女'1') txt varchar(30) -- 氏名 ); というテーブルに age | sex | txt ----+-----+------   1 | 0  | A   2 | 0  | B   2 | 1  | C   1 | 1  | D   2 | 0  | E というデータがあるとして、ここから age | 男 | 女 ----+----+----   1 | 1  | 1   2 | 2  | 1 のように集計するSQL文をご教授頂けませんでしょうか。 postgrsであれば、以下のように組んでみるのですが case演算子がMS Accessでは使えないようなので…。 select age,sum(case when sex=0 then 1 else 0 end) as 男,sum(case when sex=1 then 1 else 0 end) as 女 from t1 group by age; 宜しくお願い致します。

  • VBAで電卓を作成する

    WinXP、Excel2003を用いて、10桁の電卓を作ろうと思っていますが、エラーが多発しているので、修正したいと思っています。 〔作成するに当たっての条件〕 あとに補足で増えるかもしれません^^; ・最初の時点ではテキストボックスに0を表示しておく。 ・計算結果が10桁で収まりきらない場合はエラーボックスを表示し、直前の数値を入れる状態に戻す。EX)11÷3 ・=ボタンを押して計算結果を出すためには、「数字」「演算」「数字」の順番で3回以上押さないといけない。だから、「+3=」と押してもエラーを表示し、計算しない。 ・最初の状態で0を何回押しても0は1回しか出ない。 ・演算キーを1度でも使ったら=ボタンを押すまではテキストボックスに計算結果ではなく、直前に入力した数字を表示する。 ・=ボタンを押し、計算結果が出た後に、再度反復して=ボタンを押しても連続して結果が出ることはしない。(一般の電卓でKが表示されている状態のことを指す)その一方で、計算結果が出た後に「演算」「数値」「=」を押した場合は、新しい計算結果がテキストボックスに表示される。 ・計算過程では入力したデータは文字列として認識するが、=を押し、計算する時点において数値として認識するように変換する。 そこで、現在までに作成したのは以下の通りです。 Dim miku1As String Dim miku2 As Double Dim frg As String '1→+、2→-、3→×、4→÷ Private Sub ボタン_イコール_Click() On Error GoTo myError Select Case frg Case 1 miku2 = miku2 + miku1 Case 2 miku2 = miku2 - miku1 Case 3 miku2 = miku2 * miku1 Case 4 miku2 = miku2 / miku1 End Select TextBox1 = miku2 myError: MsgBox "エラーが発生しました。" miku1 = Null End Sub Private Sub ボタン_加算_Click() On Error GoTo myError If miku2 = 0 Then miku2 = miku1 Else Select Case frg Case 1 miku2 = miku2 + miku1 Case 2 miku2 = miku2 - miku1 Case 3 miku2 = miku2 * miku1 Case 4 miku2 = miku2 / miku1 End Select End If miku1 = Null myError: MsgBox "エラーが発生しました。" frg = 1 End Sub ~中略~ Private Sub ボタン0_Click() miku1 = miku1 & 0 TextBox1 = miku1 End Sub ~中略~ Private Sub ボタンC_Click() miku1 = Null miku2 = 0 TextBox1 = Null End Sub お手数をおかけしますが、ご教授願います。

  • Select case で条件演算子は使用可能?

     知っている方にはつまらない質問でしょうが…VB6.0でSelect case に条件演算子を使う事ってできないんでしょうか?  つまり、 if i < 0 then j = 0 else if i = 0 then j = 1 else if i > 0 then j = 2 end if  こんな感じの条件をSelect Caseで使えませんか?と言うことなんですが…

専門家に質問してみよう