先ほど作成したVBAフォームはマクロで起動できるようにしておきます。
Sub MenuOpen() ' ' MenuOpen Macro ' ' メニューをオープンします。 フォーム名.Show (vbModeless) End Sub
先ほど作成したVBAフォームはマクロで起動できるようにしておきます。
Sub MenuOpen() ' ' MenuOpen Macro ' ' メニューをオープンします。 フォーム名.Show (vbModeless) End Sub
Excelで自作マクロの起動をフォームから行います。
まずはフォームを追加します。
VBAエディタを開き、左メニューの「VBAProject」-「フォーム」で右クリックし、
「挿入」-「ユーザーフォーム」を選択します。
後はボタンをGUIで配置します。
配置後にボタンやラジオ
次に追加したフォームで右クリックし、「コードを表示」を選択し、
コード上でボタンイベントで起動したいマクロを指定します。
Private Sub PageSettingModCall_Click() Call PageSetting End Sub Private Sub SqlInsertCreateModCall_Click() Call SqlInsertCreate End Sub
選択範囲のセル書式を変更します。
Sub TblColColor() ' ' TblColColor Macro ' ' テーブル名の項目名を色付けします。 ' '選択範囲を色づけする。 With Selection.Interior .Pattern = xlSolid .PatternColorIndex = xlAutomatic .Color = 13434828 .TintAndShade = 0 .PatternTintAndShade = 0 End With '選択範囲を折り返し表示する。 With Selection.Interior .Pattern = xlSolid .PatternColorIndex = xlAutomatic .Color = 13434828 .TintAndShade = 0 .PatternTintAndShade = 0 End With '選択範囲を太字にする。 Selection.Font.Bold = True End Sub
横向けになっている表定義からSELECT文を作成します。
INSERT文の時とは異なり、sqlplusで実行できるようファイル出力しています。
また、sqlplusでSELECT文を実行するとVARCHAR2、CHARのどちらでもスペース埋めされて
結果が確認し難いので、項目ごとをパイプで結合して出力しています。
この辺sqlplusのオプションで解決出来るようにして欲しいです。
Oracleのカテゴリでも記載しましたが、「SET TRIMSPOOL ON」は行末だけという。
前提条件はコメントに記載の通り。
※DATE型に対するTO_DATEは手動。
Sub SqlSelectCreate() ' ' SqlSelectCreateYoko Macro ' ' テーブル名、項目名からSELECT文を自動生成します。 ' ' A1:テーブル名 ' A2~C2:項目名(論理名) ' A3~C3:項目名(物理名) ' A4~C4:型 ' A5~C5:サイズ ' 上記状態の時にマクロを実行する。(テーブル名、項目名(論理名)、型を利用します。) ' SQL文用変数を宣言する。 Dim sql As String Dim sqlSelect As String Dim sqlColumn As String Dim sqlFrom As String sqlSelect = "SELECT " Dim i As Long Dim MaxCol As Long MaxCol = Range("A2").End(xlToRight).Column For i = 1 To MaxCol Step 1 Cells(2, i).Activate sqlColumn = sqlColumn & ActiveCell.Value & " || '" & Chr(9) & "' || " Next i sqlColumn = Left(sqlColumn, Len(sqlColumn) - 10) sqlFrom = " FROM " & Cells(1, 1).Value & ";" sql = sqlSelect & sqlColumn & sqlFrom Open "D:/select_" & Cells(1, 1) & ".sql" For Output As #1 Print #1, "set autotrace off" Print #1, "set echo off" Print #1, "set timing on" Print #1, "set time off" Print #1, "set termout off" Print #1, "set feedback 1" Print #1, "set colsep '" & Chr(9) & "'" Print #1, "set pagesize 30000" Print #1, "set linesize 30000" Print #1, "set trimspool on" Print #1, Print #1, "col PLAN_PLUS_EXP Format a200;" Print #1, Print #1, "spool select_" & Cells(1, 1) & ".log;" Print #1, Print #1, "prompt ======================" Print #1, "prompt; データ取得" Print #1, "prompt ======================" Print #1, sql Print #1, Print #1, "set autotrace off" Print #1, "spool off;" Close #1 End Sub
横向けになっている表定義からINSERT文を作成します。
前提条件はコメントに記載の通り。
※DATE型に対するTO_DATEは手動。
Sub SqlInsertCreate() ' ' SqlInsertCreate Macro ' ' テーブル名、項目名、値からINSERT文を自動生成します。 ' ' A1:テーブル名 ' A2~C2:項目名 ' A3~C3:値 ' 上記状態の時にE2を選択し、マクロを実行する。 '//=====項目用INSERT文作成=============================== 'セルをアクティブにする。 ActiveCell.Offset(0, 0).Select 'アクティブセル列数を取得する。 Dim activCellNoCol As Long activCellNoCol = ActiveCell.Column 'ループで利用する変数を宣言する。 Dim i As Long Dim tmpStrCol As String 'アクティブセル列数-2から列数が2になるまで繰り返す For i = activCellNoCol - 2 To 2 Step -1 tmpStrCol = tmpStrCol & "RC[-" & i & "]&"",""&" Next i '項目用INSERT文を作成する。 Dim tmpInsertCol As String tmpInsertCol = "=" & Left(tmpStrCol, Len(tmpStrCol) - 5) & "&"") VALUES (""" ActiveCell.Formula = tmpInsertCol '//=====値用INSERT文作成=============================== 'セルをアクティブにする。 ActiveCell.Offset(1, 0).Select 'アクティブセル列数を取得する。 Dim activCellNoVal As Long activCellNoVal = ActiveCell.Column 'ループで利用する変数を宣言する。 Dim j As Long Dim tmpStrVal As String 'アクティブセル列数-2から列数が2になるまで繰り返す For j = activCellNoVal - 2 To 2 Step -1 tmpStrVal = tmpStrVal & "RC[-" & j & "]&""','""&" Next j '値用INSERT文を作成する。 Dim tmpInsertVal As String tmpInsertVal = "=""'""&" & Left(tmpStrVal, Len(tmpStrVal) - 7) & "&""');""" ActiveCell.Formula = tmpInsertVal '//=====テーブル用INSERT文作成=============================== 'セルをアクティブにする。 ActiveCell.Offset(-2, 0).Select 'アクティブセル列数を取得する。 Dim activCellNoTbl As Long activCellNoTbl = ActiveCell.Column 'テーブル名の位置を求める。 Dim tblNameNo As String tblNameNo = activCellNoTbl - 2 Dim tmpInsertTbl As String tmpInsertTbl = "=""INSERT INTO ""&RC[-" & tblNameNo & "]&"" (""" ActiveCell.Formula = tmpInsertTbl 'セルを初期値に戻す。 ActiveCell.Offset(1, 0).Select End Sub
現場では表定義は縦形式が多いですが、
エビデンスや他作業時は横形式の方が良い場合もあるので、マクロで変換します。
Sub TblDefConversion() ' ' TblDefConversion Macro ' ' テーブル定義を縦から横に変換する。 ' 変換後のエクセル用変数を宣言する。 Dim newBook As String Dim NewWorkSheet As Worksheet ' 変換後のエクセルを追加する。 Workbooks.Add newBook = ActiveWorkbook.Name ' 変換前のエクセル用変数を宣言する。 Dim oldWorkBook As Workbook Set oldWorkBook = Workbooks("Book1.xlsx") Dim oldWorkSheet As Worksheet Dim tblNameRowPoint As Long ' テーブル名が存在する行数 Dim tblNameCellPoint As Long ' テーブル名が存在する列数 tblNameRowPoint = 4 tblNameCellPoint = 21 Dim colNameLogicalRowPoint As Long ' 項目名(論理名)が存在する行数 Dim colNameLogicalCellPoint As Long ' 項目名(論理名)が存在する列数 Dim colNamePhysicalRowPoint As Long ' 項目名(物理名)が存在する行数 Dim colNamePhysicalCellPoint As Long ' 項目名(物理名)が存在する列数 Dim colTypeRowPoint As Long ' 型が存在する行数 Dim colTypeCellPoint As Long ' 型が存在する列数 Dim colSizeRowPoint As Long ' サイズが存在する行数 Dim colSizeCellPoint As Long ' サイズが存在する列数 colNameLogicalRowPoint = 9 colNameLogicalCellPoint = 2 colNamePhysicalRowPoint = colNameLogicalRowPoint colNamePhysicalCellPoint = 13 colTypeRowPoint = colNameLogicalRowPoint colTypeCellPoint = 24 colSizeRowPoint = colNameLogicalRowPoint colSizeCellPoint = 28 ' 変換前のエクセルシート分繰り返す。 For Each oldWorkSheet In oldWorkBook.Worksheets ' 変換後のエクセルシートとA1セルに変換前のエクセルシート名を設定する。 ' エクセルでは関数に()をつけると戻り値を伴う。 Workbooks(newBook).Activate Set NewWorkSheet = Worksheets.Add() MsgBox oldWorkSheet.Cells(tblNameRowPoint, tblNameCellPoint).Value NewWorkSheet.Name = oldWorkSheet.Cells(tblNameRowPoint, tblNameCellPoint).Value Cells(1, 1).Value = oldWorkSheet.Cells(tblNameRowPoint, tblNameCellPoint).Value ' 変換前エクセルの項目名の最初と最後を設定する。 oldWorkBook.Activate oldWorkSheet.Activate Dim i As Long Dim MaxRow As Long MaxRow = oldWorkSheet.Cells(Rows.Count, colNameLogicalCellPoint).End(xlUp).Row ' 変換前エクセルの項目名の最初から最後までを繰り返す。 For i = colNameLogicalRowPoint To MaxRow ' 項目名(論理名)、項目名(物理名)、型、サイズを取得する。 Dim colNameLogical As String Dim colNamePhysical As String Dim colType As String Dim colSize As String colNameLogical = Cells(i, colNameLogicalCellPoint).Value colNamePhysical = Cells(i, colNamePhysicalCellPoint).Value colType = Cells(i, colTypeCellPoint).Value colSize = Cells(i, colSizeCellPoint).Value ' 変換後のエクセルに各々の値を取得する。 Workbooks(newBook).Activate NewWorkSheet.Cells(2, i - colNameLogicalRowPoint + 1).Value = colNameLogical NewWorkSheet.Cells(3, i - colNamePhysicalRowPoint + 1).Value = colNamePhysical NewWorkSheet.Cells(4, i - colTypeRowPoint + 1).Value = colType NewWorkSheet.Cells(5, i - colSizeRowPoint + 1).Value = colSize ' 変換前のエクセルをアクティブにしておく。 oldWorkBook.Activate Next i Next oldWorkSheet End Sub
納品用に横印刷、左上にファイル名、右上に日付、
真ん中下にページ数/総ページ数を設定します。
※縦印刷は未記載。
Sub PageSetting() ' ' PageSetting Macro ' ' シートの初期設定を行います。 ' ' 印刷初期設定を行う。 ' 印刷高速設定をfalseにして設定する。 Application.PrintCommunication = False With ActiveSheet.PageSetup .CenterHorizontally = False .CenterVertically = False .Orientation = xlLandscape .Draft = False .PaperSize = xlPaperA4 .FirstPageNumber = xlAutomatic .Order = xlDownThenOver .BlackAndWhite = False .Zoom = False .FitToPagesWide = 1 .FitToPagesTall = False .PrintErrors = xlPrintErrorsDisplayed .OddAndEvenPagesHeaderFooter = False .DifferentFirstPageHeaderFooter = False .ScaleWithDocHeaderFooter = True .AlignMarginsHeaderFooter = True End With ' 印刷高速設定をtureに戻す。 Application.PrintCommunication = True ' 印刷高速設定を設定せずに設定する。(印刷高速設定を設定すると設定不可) With ActiveSheet.PageSetup .LeftHeader = "&F" .CenterHeader = "" .RightHeader = "&D" .LeftFooter = "" .CenterFooter = "&P/&N" .RightFooter = "" .LeftMargin = Application.InchesToPoints(0.708661417322835) .RightMargin = Application.InchesToPoints(0.708661417322835) .TopMargin = Application.InchesToPoints(0.748031496062992) .BottomMargin = Application.InchesToPoints(0.748031496062992) .HeaderMargin = Application.InchesToPoints(0.31496062992126) .FooterMargin = Application.InchesToPoints(0.31496062992126) .PrintHeadings = False .PrintGridlines = False .PrintComments = xlPrintNoComments .PrintQuality = 600 .EvenPage.LeftHeader.Text = "" .EvenPage.CenterHeader.Text = "" .EvenPage.RightHeader.Text = "" .EvenPage.LeftFooter.Text = "" .EvenPage.CenterFooter.Text = "" .EvenPage.RightFooter.Text = "" .FirstPage.LeftHeader.Text = "" .FirstPage.CenterHeader.Text = "" .FirstPage.RightHeader.Text = "" .FirstPage.LeftFooter.Text = "" .FirstPage.CenterFooter.Text = "" .FirstPage.RightFooter.Text = "" End With ' 文字初期設定を行う。 Cells.Select With Selection.Font .Name = "MS Pゴシック" .Size = 9 .Strikethrough = False .Superscript = False .Subscript = False .OutlineFont = False .Shadow = False .Underline = xlUnderlineStyleNone .ThemeColor = xlThemeColorLight1 .TintAndShade = 0 .ThemeFont = xlThemeFontNone End With Selection.NumberFormatLocal = "@" Range("A1").Select End Sub
設計書の記述内容を強調したり、
エビデンスの確認箇所を強調したりする際に
赤い太枠をよく使うのでマクロで作成します。
Sub RedBox() ' ' RedBox Macro ' ' 赤い太枠四角線を作ります。 ActiveSheet.Shapes.AddShape(msoShapeRectangle, Selection.Left, Selection.Top, 96.75, 96.75).Select Selection.ShapeRange.Line.Weight = 2.25 Selection.ShapeRange.Line.Visible = msoTrue Selection.ShapeRange.Line.Style = msoLineSingle Selection.ShapeRange.Line.ForeColor.SchemeColor = 10 Selection.ShapeRange.Line.Visible = msoTrue Selection.ShapeRange.Fill.Visible = msoFlase End Sub
納品物はA1セルにカーソルが選択されていないといけないことが多いので、
マクロでA1を選択します。
Sub TopCursor() ' ' TopCursor Macro ' ' A1にカーソルを合わせます。 ' ' 画面のチラつきの防止設定を行う。 Application.ScreenUpdating = False ' 全シート分繰り返す。 Dim Sht As Worksheet For Each Sht In Worksheets ' シートを選択する。 Sht.Select ' スクロールバーを上にする。 Dim i As Integer For i = 1 To Windows(1).Panes.Count Windows(1).Panes(i).ScrollColumn = 1 Windows(1).Panes(i).scrollRow = 1 Next i ' A1セルを選択する。 ActiveSheet.Cells(1, 1).Select Next Sht ' 先頭シートを選択する。 Worksheets(1).Activate ' 画面のチラつきの防止設定を元に戻す。 Application.ScreenUpdating = True End Sub
JavaファイルだとSJIS、propertiesだとSJISまたはUTF-8の
どちらでも定義されている”氏名”という単語を
ファイル名と行数を出力しながらgrepしたい。
検索してみると下記のような方法が多かったです。
grep -rn `echo "氏名" | nkf -s` *.java *.properties | nkf -w
上記方法だと、入力値の”氏名”をSJISに変換してからgrepしているため、
SJISで書かれているJavaファイルしかgrepできないんじゃ?と思い、
for文を利用してみることに。
(そもそも上記方法だとなぜかgrepすら出来ず。なぜだろう。。)
for X in `find ( -name "*.java" -or -name "*.properties" )`; do nkf -w $X | grep -rn "氏名" | while read line; do echo "$X:$line"; done done
./Sample.java:15: //氏名を変換 ./test_utf8.properties:1:#氏名を定義 ./test_sjis.properties:1:#氏名を定義
これでファイル名と行数とそれに対するgrep結果が得られました。
findでHITしたファイルを一時変数に格納し、「nkf -w」で全てUTF-8に変換してからgrepしてます。
次にgrep結果をwhileで繰り返しながら一時変数(ファイル)とgrep結果を出力。
もうシェル作って引数取ればいいじゃないと思いますが、1行でやりたかったんです。