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

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

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

3回答

4290閲覧

VBA コードのインデントについて

rebell

総合スコア19

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

1グッド

0クリップ

投稿2018/10/31 07:04

編集2018/10/31 07:06

VBA応用(ADOでデータを取得する。)

上記URLのサイトを見てVBAの学習をしております。
以前はわからないコードについて質問させていただきました。

ソースレビューを受け手直しをしたのですがまだ見づらいと思っています。

誰が見ても見やすくするにはどうすればいいか教えてくださると助かります。

言語はjavaが使えます

よろしくお願いします。

VBA

1Option Explicit 2 3'スコープがPrivateになっている定数 4 5Private Const g_cnsTitle = "ADOによるMDBデータ取得" 6'MicrosoftのOLEDBを使うことを宣言 7Private Const g_cnsAdoConnectString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" 8'Accessデーターベースのファイル名? 9Private Const g_cnsMdbName = "SampleCorp1.mdb" 10 11Public Sub GetMDBDateByADO() 12 13 '変数を定義 14 15 Dim objFso As FileSystemObject ' FileSystemObject 16 Dim dbCon As ADODB.Connection ' ADODB.Connection 17 Dim dbRes As ADODB.Recordset ' ADODB.Recordset 18 Dim objSh As Worksheet ' Excel.Worksheet 19 Dim strFilename As String ' フルパスファイル名 20 Dim strConnection As String ' 接続文字列 21 Dim strSQL As String ' SQL文編集WORK 22 Dim strToday As String ' SQL文本日編集WORK 23 Dim lngRow As Long ' 行INDEX 24 Dim lngCol As Long ' 列INDEX 25 26 'データベースのあるファイルのパス 27 28 Set objFso = New FileSystemObject 29 strFilename = objFso.BuildPath(ThisWorkbook.Path, g_cnsMdbName) ' 30 Set objFso = Nothing 'オブジェクトへの参照を解除 31 32 '接続文字列の編集 33 strConnection = g_cnsAdoConnectString & strFilename & "';" 34 35 'データベースへの接続 36 Set dbCon = New ADODB.Connection 37 dbCon.Open strConnection 38 39 'クライアントカーソル設定 40 dbCon.CursorLocation = adUseClient 'カーソルをクライアント側に持つか、サーバ側(例:Access)に持つかの設定 mdbはどちらにも持たない? 41 42 '参照SQL文 43 strToday = "#" & Format(Date, "yyyy-mm-dd") & "#" '変換? 44 45 strSQL = "SELECT H.[BUSYO_CD]" ' (00)部署コード 46 strSQL = strSQL & " , B.[BUSYO_NM]" ' (01)部署名 47 strSQL = strSQL & " , H.[YAKU_CD]" ' (02)役職コード 48 strSQL = strSQL & " , Y.[YAKU_NM]" ' (03)役職名 49 strSQL = strSQL & " , H.[SCD]" ' (04)社員コード 50 strSQL = strSQL & " , S.[KANJI_SEI]+S.[KANJI_MEI]" ' (05)氏名(漢字) 51 strSQL = strSQL & " , S.[KANA_SEI]+S.[KANA_MEI]" ' (06)氏名(カナ) 52 strSQL = strSQL & " , S.[NYUSYA_YMD]" ' (07)入社日 53 strSQL = strSQL & " , S.[TAISYOKU_YMD]" ' (08)退職日 54 55 strSQL = strSQL & " FROM ((([MST_HAIZOKU] AS H" '取得したいテーブルを指定 56 strSQL = strSQL & " INNER JOIN [MST_SYAIN] AS S ON H.[SCD]=S.[SCD])" 'テーブルを内部結合 57 strSQL = strSQL & " LEFT OUTER JOIN [MST_BUSYO] AS B ON H.[BUSYO_CD]=B.[BUSYO_CD])" '外部結合 58 strSQL = strSQL & " LEFT OUTER JOIN [MST_YAKU] AS Y ON H.[YAKU_CD]=Y.[YAKU_CD])" '外部結合 59 strSQL = strSQL & " WHERE S.[NYUSYA_YMD]<=" & strToday '入社日と本日日付を比較・制限して検索 60 strSQL = strSQL & " AND (S.[TAISYOKU_YMD] IS NULL OR S.[TAISYOKU_YMD]>" & strToday & ")" ' 61 strSQL = strSQL & " ORDER BY H.[BUSYO_CD],H.[YAKU_CD],H.[SCD];" 'クエリの結果を並べ替えする 62 63 '参照SQL文の発行 64 Set dbRes = New ADODB.Recordset 65 dbRes.Open strSQL, dbCon, adOpenKeysetm, adLockReadOnly 'Openステートメント ファイル開く 66 67 '画面描画更新停止 描画を停止し処理を高速化 68 Call GP_StopSCUPD '標準モジュール 「ZZZ_Module」内の「GP_StopSCUPD」プロシージャを呼び出し 69 70 'シートの初期化 71 Set objSh = ThisWorkbook.Worksheets(1) 72 With objSh 73 If .FilterMode Then .ShowAllData 74 .Rows("2:" & .Rows.Count).ClearContents 75 IngRow = 1 76 77 '先頭レコードからEOFまで繰り返す End of Fileの略 78 Do Until dbRes.EOF 79 80 '行を加算 81 IngRow = IngRow + 1 82 83 '全列をシートに展開 84 For IngCol = 0 To 8 85 .Cells(IngRow, IngCol + 1).Value = dbRes.Fields(lngCol).Value 86 Next IngCol 87 '次のレコードに移る 88 dbRes.MoveNext 89 Loop 90 91 End With 92 93 ' レコードセット、データベースを閉じる 94 dbRes.Close 95 Set dbRes = Nothing 96 dbCon.Close 97 Set dbCon = Nothing 98 99 ' 画面描画更新復帰 100 Call GP_StartSCUPD 101 102End Sub
dotnetuseryamag👍を押しています

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

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

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

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

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

guest

回答3

0

VBA初心者としては上出来だと思いますよ!
コメントもVBAの界隈ではこの程度でちょうどいいんじゃないかと。

では、上級者への道として幾つか補足を。

●シートオブジェクト
「Set objSh = ThisWorkbook.Worksheets(1)」で、
Worksheet型の変数にセットしているのはOKですが、
自分のブックであれば、変数にセットせずに使えますよ~

VBE画面でモジュールの上に「Sheet1」とか見えてると思いますが、
これはシート自体のオブジェクト名で、
プロパティで「Sheet_Main」等と変えることができ、
コードを書く時に直接「Sheet_Main.Cells(1,2)」等と書けるので、
変数が不要になります。
※確か、Nothing しちゃうとバグると思うので、そこだけ気を付けてください。

●行、列の定義
「.Rows("2:" & .Rows.Count)」や、
「For IngCol = 0 To 8 」で、
直接「2」等と番号を使ってますが、
別途定義しないと、行・列の変化があった時に
コードの調整に非常に多くの時間を割くことになってしまいます。

1つ目の方法は、Constを使って定義する方法があります。

しかし、↓のように定義量が多いと、やはり変化があった時に調整が面倒です。

VBA

1Public Const Col_Code As Long = 1 2'←ここにNo等、新しい列を追加するとなると、↓の定義を+1等と変えなきゃいけなくなる。。。 3Public Const Col_Name As Long = 2 4Public Const Col_Address As Long = 3 5Public Const Col_xxx4 As Long = 4 6Public Const Col_xxx5 As Long = 5 7Public Const Col_xxx6 As Long = 6 8Public Const Col_xxx7 As Long = 7 9Public Const Col_xxx8 As Long = 8

2つ目の方法は、Enumを使って定義する方法があります。
自分は、こちらをオススメします。

VBA

1Public Enum E_Col_Main 2 Data_S = 2 'データ開始列 3 Type_ = E_Col_Main.Data_S 4 Module 5 Equal 6 UpDate 7 UserName 8 UserComment 9 UpCount 10 Data_E = E_Col_Main.UpCount 'データ終了列 11End Enum

Enumは=2等と定義した以降は、自動で1つずつインクリメントしてくれるので、
開始番号だけ定義すれば、以降は番号指定が不要になります。

また、列を途中で追加したい、列を入れ替えたい、という変化に対しても、
定義を1つ追加する、順番を入れ替える、という調整で済むようになります。

上記の例で「Data_S」「Data_E」と定義しているのは、
データの開始列、終了列、を定義していて、
「「For IngCol = 0 To 8 」のように
「全列に対して処理する」という場合に使用する為です。

変数名をみれば、全列に対して処理しようとしているのか、
それとも一部に対して処理したいのか、
という事が分かりやすくなると思います。

※開始列、最終列に定義を追加する場合には、
定義を修正する必要があるので、そこだけは気を付けてください。

投稿2018/11/01 00:36

ExcelVBAer

総合スコア1175

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

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

ExcelVBAer

2018/11/01 00:39

余談ながら、参考書としては「VBAを実務で使い倒す技術」をおすすめしています。 プログラマ寄りに書いている内容なので、 色々と役に立つと思います。 余談ついでに、自分は、変数は使用する直前で宣言する派です。 その方が開発やデバッグがしやすくなると思っています。
guest

0

ざっと見た感じでは綺麗に書けていると思いますよ。
2点気になったところ。
シートの初期化処理のWith内のインデントがずれているのはコピペミスでしょうか?
あと8タブになっているのもコピペミスでしょうか?
ミスでないなら4タブにしたほうがよいかと。

可読性の良し悪しを見てもらいたいなら、VBE上とまったく同じ状態で掲載されているか確認してくださいね。

投稿2018/10/31 07:23

ttyp03

総合スコア16996

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

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

rebell

2018/10/31 07:39

回答ありがとうございます。 With内なのですがVBを触ってまだ浅く、With内のIfとForをどうインデントしてあげたらいいのかわからずズレてる状態です。 8タブと言うのは半角8スペースと言う認識で合っていますか?
ttyp03

2018/10/31 07:43

インデントについてはVBEで編集している限りでは自動でやってくれるので、ヘタにいじらなければいいと思いますよ。 もし自動でやってなかったら、オプションの「自動インデント」がチェックされているか確認してください。 8タブはその認識であっています。 これもオプションに「タブ間隔」ってのがあるので確認してみてください。
rebell

2018/10/31 07:45

ありがとうございます。 インデント自分で入れていたのでオプションを見てみることにします。
sazi

2018/10/31 07:58

インデントによってコメントが見切れたりするのが嫌で、2タブにしちゃってます、私。
ttyp03

2018/10/31 23:25

さすがに2タブだと詰まりすぎて私はダメですわ。 長年4タブです。
guest

0

ベストアンサー

一般的には、構造を持った文の開始行と、その終了の行は同じインデントで、その中味は1段下げます。

VBA

1 With objSh 2 If .FilterMode Then .ShowAllData 3 .Rows("2:" & .Rows.Count).ClearContents 4 IngRow = 1 5 Do Until dbRes.EOF 6 IngRow = IngRow + 1 7 8 '全列をシートに展開 9 For IngCol = 0 To 8 10 .Cells(IngRow, IngCol + 1).Value = dbRes.Fields(lngCol).Value 11 Next IngCol 12 dbRes.MoveNext 13 Loop 14 End With

あとは、継続行のインデントは臨機応変でしょうか。

また、逐語的なコメントは書かないのが普通です。

投稿2018/10/31 07:22

otn

総合スコア84423

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

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

rebell

2018/10/31 07:34

回答ありがとうございます IfやForの中身のインデント気をつけるようにします。 継続行というのを始めて聞き調べてきました。 sql文が長いと思い改行を入れたらエラーがすごい出たのですが、エラーが出ない改行方法があるのですね。 どういう動きをしているか見てわかるようにコメントが多くなってしまいました。 いいコメントが書けるように心がけます。
otn

2018/10/31 07:44 編集

継続行は、 If a = 1 or _ b = 3 Then のように書きます。「空白」「下線」「改行」です。 > どういう動きをしているか見てわかるようにコメントが多くなってしまいました。 コードを日本語に翻訳したようなコメントは、見づらくなるので、書きません。
rebell

2018/10/31 07:50

確かに同じことを何回も書く必要は無いですね。 コメントの書き方の勉強もします。
sazi

2018/10/31 07:51

SQLを継続行で記述すると途中にコメントが付けられないので、個人的にはお勧めしません。
rebell

2018/10/31 07:56

@sazi  継続行を回避した場合長くなってしまったSQLはどう成形してあげるのが見る人に取って優しいですか?
sazi

2018/10/31 08:04 編集

ベースになるものをSQL単独で成形して、A5:SQLの「ソース文字列生成」でできたものを貼り付けしています。 SQL単独での見易さも同じで、ブロックがインデントで揃えられていることですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問