SQLの窓

2019年02月10日


テーブル設計書作成 : VBScript + Excel.Application + SQLServer

※ 実行はコマンドプロンプトから、cscript table-spec.wsf として下さい。
※ Excel でテーブル設計書を作成する部分は他のデータベースでも可能ですが、それ用の SQL を考える必要があります。



table-spec.wsf
<JOB>
<RUNTIME>
<DESCRIPTION>
*******************************************************************
 プログラム名 : SQLServer 用表情報のレポート (複数実行)
*******************************************************************
</DESCRIPTION>
<EXAMPLE>

引数無し
</EXAMPLE>
</RUNTIME>

<COMMENT>
************************************************************
 対象テーブルリスト
************************************************************
</COMMENT>
<RESOURCE id="TableList">

社員マスタ
商品マスタ

</RESOURCE>

<COMMENT>
************************************************************
 オブジェクト定義
************************************************************
</COMMENT>
<REFERENCE object="ADODB.Connection" />
<OBJECT id="Cn" progid="ADODB.Connection" />
<OBJECT id="Rs" progid="ADODB.Recordset" />
<OBJECT id="ExcelApp" progid="Excel.Application" />
<OBJECT id="WshShell" progid="WScript.Shell" />
<OBJECT id="Fso" progid="Scripting.FileSystemObject" />

<COMMENT>
************************************************************
 外部スクリプト定義
************************************************************
</COMMENT>

<COMMENT>
************************************************************
 カレントスクリプト
************************************************************
</COMMENT>

<SCRIPT language=VBScript>

Dim str,strMessage,Target,strCurDir

' **********************************************************
' 作成される Excel ブック
' **********************************************************
Target = "table_spec_ss.xlsx"
strCurDir = WScript.ScriptFullName
strCurDir = Replace( strCurDir, WScript.ScriptName, "" )
Target = strCurDir & Target

Dim strSERVER,strDATABASE,strUSER,strPASS

' **********************************************************
' データベース接続情報
' **********************************************************
strSERVER = ".\sqlexpress"
strDATABASE = "lightbox"
strUSER = "sa"
strPASS = "password"

' **********************************************************
' コマンドプロンプトより起動される為の処理
' **********************************************************
str = WScript.FullName
str = Right( str, 11 )
str = Ucase( str )
if str <> "CSCRIPT.EXE" then
	strMessage = "コマンドプロンプトより cscript " & WScript.ScriptFullName
	strMessage = strMessage & " と指定して実行して下さい   " & vbCrLf & vbCrLf
	strMessage = strMessage & "( この文字列をクリップボードにコピーしたい場合は"
	strMessage = strMessage & " ctrl+c です )"
	WScript.Echo strMessage
	WScript.Quit
end if

' **********************************************************
' Excel 用定数
' **********************************************************
' https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.office.interop.excel.xlpapersize?view=excel-pia
Const xlPaperB4 = 12

Const xlContinuous = 1
Const xlDash = -4115
Const xlDashDot = 4
Const xlDashDotDot = 5
Const xlDot = -4118
Const xlDouble = -4119
Const xlSlantDashDot = 13
Const xlLineStyleNone = -4142

Const xlHairline = 1
Const xlMedium = -4138
Const xlThick = 4
Const xlThin = 2

Const xlInsideHorizontal = 12
Const xlInsideVertical = 11
Const xlDiagonalDown = 5
Const xlDiagonalUp = 6
Const xlEdgeBottom = 9
Const xlEdgeLeft = 7
Const xlEdgeRight = 10
Const xlEdgeTop = 8

Const xlAutomatic = -4105

Const xlMaximized = -4137
Const xlMinimized = -4140
Const xlNormal = -4143

Const xlGeneral = 1
Const xlLeft = -4131
Const xlCenter = -4108
Const xlRight = -4152
Const xlFill = 5
Const xlJustify = -4130
Const xlCenterAcrossSelection = 7
Const xlDistributed = -4117
Const xlTop = -4160
Const xlBottom = -4107

Dim aTable,Result,Query,Query2,nCnt,strCol,aCol,nRows,nRowHeight
Dim MyBook,bAction,strSystemName,strSubName
Dim nColX,nColY,strSheetName,strBaseSheet
Dim aData

ExcelApp.Visible = False
strBaseSheet = "テーブル設計雛形"
strSystemName = "販売管理システム"
strSubName = "売上管理"
Query = "sp_columns "

' **********************************************************
' Excel 初期処理
' **********************************************************
aTable = Split( getResource("TableList"), vbCrLf )

' **********************************************************
' ブック作成
' **********************************************************
Set MyBook = CreateBook(Target)
if not IsObject( MyBook ) then
	' 初期処理エラーの為、直接終了
	ExcelApp.Quit
	' エラーメッセージの表示
	Wscript.Echo MyBook
	Wscript.Quit
end if

' **********************************************************
' DB 接続
' **********************************************************
Result = SQS_DBConnect( Cn, strSERVER, strDATABASE, strUSER, strPASS )
if Result <> "" then
	Wscript.Echo Result
	Wscript.Quit
end if

' **********************************************************
' 読み出し
' **********************************************************
Wscript.Echo "処理を開始しました。しばらくお待ち下さい"
bAction = False
For i = 0 to Ubound( aTable )
	if Trim( aTable(i) ) <> "" then
		if DBGet( Cn, Rs, Query & Ss( aTable(i) ), False ) then
			' ************************************************
			' Excel 処理
			' ************************************************
			nColX = 2
			nColY = 6
			if not bAction then
				bAction = True
				Call AddSheetLast( MyBook, strBaseSheet )
				Call DeleteSheet(MyBook,"Sheet1" )
				Call ColumnInit(MyBook,strBaseSheet)
				Wscript.Echo strBaseSheet & " を追加しました"
			end if
			strSheetName = ExcelCopySheet( MyBook, strBaseSheet, aTable(i) )
			strSaveSheetName = strSheetName
			Call ExcelSetCell(MyBook, strSheetName, 2, 2, strSystemName )
			Call ExcelSetCell(MyBook, strSheetName, 4, 2, strSubName )
			Call ExcelSetCell(MyBook, strSheetName, 10, 2, aTable(i) )
			Call ExcelSetCell(MyBook, strSheetName, 2, 4, aTable(i) )

			nCnt = 1
			nRowCnt = 1
			nSheetCount = 1
			Redim aData(0)
			Do While not Rs.EOF
				Redim Preserve aData(nCnt)
				aData(nCnt) = Rs.Fields("COLUMN_NAME").value & ""
				' ************************************************
				' Excel 処理
				' ************************************************
				Call ExcelSetCell(MyBook, strSheetName, nColX, nColY, Rs.Fields("COLUMN_NAME").value & "")
				Call ExcelSetCell(MyBook, strSheetName, nColX+2, nColY, Ucase(Rs.Fields("TYPE_NAME").value & "") )
				if Ucase( Rs.Fields("TYPE_NAME").value & "" ) = "VARCHAR" or _
					Ucase( Rs.Fields("TYPE_NAME").value & "" ) = "CHAR" or _
					Ucase( Rs.Fields("TYPE_NAME").value & "" ) = "NVARCHAR"or _ 
					Ucase( Rs.Fields("TYPE_NAME").value & "" ) = "NCHAR" then
					Call ExcelSetCell(MyBook, strSheetName, nColX+3, nColY, Rs.Fields("PRECISION").value & "")
				end if
				if Ucase( Rs.Fields("TYPE_NAME").value & "" ) = "DECIMAL" then
					Call ExcelSetCell(MyBook, strSheetName, nColX+3, nColY, Rs.Fields("PRECISION") & "")
					Call ExcelSetCell(MyBook, strSheetName, nColX+4, nColY, Rs.Fields("SCALE").value & "")
				end if
				nColY = nColY + 1

				Rs.MoveNext
				nCnt = nCnt + 1
				nRowCnt = nRowCnt + 1
				if nRowCnt > 65 then
					nRowCnt = 1
					nColX = 2
					nColY = 6
					nSheetCount = nSheetCount + 1
					strSheetName = ExcelCopySheet( MyBook, strBaseSheet, aTable(i) & "(" & nSheetCount & ")" )
					Call ExcelSetCell(MyBook, strSheetName, 2, 4, aTable(i) )
				end if
			Loop
			strSheetName = strSaveSheetName

			Result = ""
			Query2 = "sp_helpindex "
			if DBGet( Cn, Rs, Query2 & Ss( aTable(i) ), False ) then
				Do While not Rs.EOF
					if Left( Rs.Fields("index_name").value & "", 1 ) <> "_" then
						if InStr( Rs.Fields("index_description").value & "" , "primary key" ) > 0 then

							nCnt = 1
							strCol = Rs.Fields("index_keys").value & ""
							aCol = Split( strCol, ", " )

							For j = 0 to Ubound( aCol )
								For k = 1 to Ubound( aData )
									if aCol( j ) = aData( k ) then
										Call ExcelSetCell(MyBook, strSheetName, 11, 5 + k, j + 1 )
									end if
								Next
							Next

							Exit Do

						end if

					end if
					Rs.MoveNext
				Loop
			end if

			Wscript.Echo strSheetName & " を追加しました"
		end if
	end if

Next


' **********************************************************
' 接続解除
' **********************************************************
Call DBClose( Rs )
Call DBClose( Cn )

' **********************************************************
' 処理終了
' **********************************************************
Call ExcelSave(MyBook)
Call ExcelQuit(MyBook)

Wscript.Echo "処理が完了しました"

Call ExcelLoad(Target)


' **********************************************************
' Excel 出力用 初期処理
' **********************************************************
Function ColumnInit(MyBook,SheetName)

	' 行数
	nRows = 65
	nRowHeight = 13.5

	Call Format_Table(MyBook,SheetName)
	Call Format_Page(MyBook)

End Function

' **********************************************************
' Excel 処理関数
' **********************************************************
' ******************************************************
' シート名によるシート複写
' ******************************************************
Function ExcelCopySheet(MyBook, strSheetName, strNewSheetName)

	MyBook.Sheets(strSheetName).Copy (MyBook.Sheets(strSheetName))

	on error resume next
	MyBook.ActiveSheet.Name = strNewSheetName
	on error goto 0

	ExcelCopySheet = MyBook.ActiveSheet.Name

End Function

' ************************************************
' Excel ブック作成
' ************************************************
function CreateBook(BookPath)

	ExcelApp.DisplayAlerts = False

	ExcelApp.Workbooks.Add
	nBooks = ExcelApp.Workbooks.Count
	Set CreateBook = ExcelApp.Workbooks( nBooks )
	CreateBook.Activate

	on error resume next
	Call CreateBook.SaveAs( BookPath )
	if Err.Number <> 0 then
		CreateBook = "ERROR:" & Err.Description
	end if
	on error goto 0

End Function

' ******************************************************
' 終了
' ******************************************************
Function ExcelQuit(WorkBook)

	If TypeName(WorkBook) = "Workbook" Then
		' 保存した事にする
		WorkBook.Saved = True
	End If
	If IsObject(ExcelApp) Then
		ExcelApp.Quit
	End If

End Function

' ******************************************************
' セルへのデータセット
' ******************************************************
Function ExcelSetCell(MyBook, strSheetName, x, y, Data)

	MyBook.Sheets(strSheetName).Cells(y, x) = Data

End Function

' ******************************************************
' 先頭にシートを追加
' ******************************************************
function AddSheetTop( MyBook, SheetName )

	Dim Worksheet
	Dim Worksheet2

	Set Worksheet = MyBook.Worksheets( 1 )
	Worksheet.Activate
	Workbook.Worksheets.Add
	Set Worksheet2 = Workbook.ActiveSheet
	on error resume next
	Worksheet2.Name = SheetName
	on error goto 0

	AddSheetTop = Worksheet2.Name

end function

' ******************************************************
' 最後にシートを追加
' ******************************************************
function AddSheetLast( MyBook, SheetName )

	Dim Worksheet
	Dim Worksheet2
	Dim nSheets

	nSheets = MyBook.Worksheets.Count
	Set Worksheet = MyBook.Worksheets( nSheets )
	Worksheet.Activate
	Call MyBook.Worksheets.Add(,Worksheet)
	Set Worksheet2 = MyBook.ActiveSheet
	on error resume next
	Worksheet2.Name = SheetName
	on error goto 0

	AddSheetLast = Worksheet2.Name

end function

' ******************************************************
' Excel 実行 ( NT5.0 以上 )
' ******************************************************
Function ExcelLoad(strPath)

	Call WshShell.Run( "RunDLL32.EXE shell32.dll,ShellExec_RunDLL " & _
		strPath )

End Function

' ******************************************************
' 上書き保存
' ******************************************************
Function ExcelSave(MyBook)

	MyBook.Save

End Function

' ******************************************************
' シートを削除
' ******************************************************
function DeleteSheet( MyBook, SheetName )

	Dim Worksheet

	Set Worksheet = MyBook.Worksheets( SheetName )

	on error resume next
	Worksheet.Delete
	on error goto 0

end function

' ******************************************************
' 指定行の高さを設定
' ******************************************************
Function ExcelSetRowHeight(MyBook, strSheetName, row, Height)

	MyBook.Sheets(strSheetName).Rows(row).RowHeight = _
	Height

End Function

' ******************************************************
' 指定列の幅を設定
' ******************************************************
Function ExcelSetColumnWidth(MyBook, strSheetName, column, Width)

	Dim strColumn

	strColumn = Chr(Asc("A") + column - 1)

	MyBook.Sheets(strSheetName).Columns(strColumn).ColumnWidth = _
	Width

End Function

' ******************************************************
' 範囲選択
' ******************************************************
Function ExcelRange(MyBook, strSheetName, nX1, nY1, nX2, nY2 )

	Dim Sheet,strRange

	Set Sheet = MyBook.Sheets(strSheetName)
	Sheet.Select
	strRange = Chr(Asc("A") + nX1 - 1) & nY1 & ":"
	strRange = strRange & Chr(Asc("A") + nX2 - 1) & nY2
	Sheet.Range(strRange).Select

End Function

' ******************************************************
' 範囲の上に罫線
' ******************************************************
Function ExcelLine( nLineType, nWeight )

	With ExcelApp.Selection.Borders(xlEdgeTop)
		.LineStyle = nLineType
		.ColorIndex = xlAutomatic
		.Weight = nWeight
	End With

End Function

' ******************************************************
' 範囲の右に罫線(*追加*)
' ******************************************************
Function ExcelLineRight( nLineType, nWeight )

	With ExcelApp.Selection.Borders(xlEdgeRight)
		.LineStyle = nLineType
		.ColorIndex = xlAutomatic
		.Weight = nWeight
	End With

End Function

' ******************************************************
' 範囲に罫線
' ******************************************************
Function ExcelBox( nLineType, nWeight )

	With ExcelApp.Selection.Borders(xlEdgeTop)
		.LineStyle = nLineType
		.ColorIndex = xlAutomatic
		.Weight = nWeight
	End With
	With ExcelApp.Selection.Borders(xlEdgeLeft)
		.LineStyle = nLineType
		.ColorIndex = xlAutomatic
		.Weight = nWeight
	End With
	With ExcelApp.Selection.Borders(xlEdgeRight)
		.LineStyle = nLineType
		.ColorIndex = xlAutomatic
		.Weight = nWeight
	End With
	With ExcelApp.Selection.Borders(xlEdgeBottom)
		.LineStyle = nLineType
		.ColorIndex = xlAutomatic
		.Weight = nWeight
	End With

End Function

' ******************************************************
' 文字列の横位置を指定(*追加*)
' ******************************************************
Function ExcelHAlign()

	ExcelApp.Selection.HorizontalAlignment = xlCenterAcrossSelection

End Function
Function ExcelHAlign2()

	ExcelApp.Selection.HorizontalAlignment = xlCenter

End Function

' ******************************************************
' 文字列の縦位置を指定(*追加*)
' ******************************************************
Function ExcelVAlign()

	ExcelApp.Selection.VerticalAlignment = xlCenter

End Function

' ******************************************************
' シート名によるシート選択
' ******************************************************
Function ExcelSelectSheet(MyBook, strSheetName)

	MyBook.Sheets(strSheetName).Select

End Function

' ******************************************************
' テーブル設計書用フォーマット
' ******************************************************
Function Format_Table(MyBook,SheetName)

	'テーブル設計書フォーマット作成
	Call ExcelSelectSheet(MyBook, SheetName)
'	Call Format_Page(MyBook)

	Call ExcelSize_Table(MyBook, SheetName)
	Call ExcelLine_Table(MyBook, SheetName)
	Call ExcelSetText_Table(MyBook, SheetName)

End Function

' ******************************************************
' セルサイズの設定
' ******************************************************
Function ExcelSize_Table(MyBook, Target)

	Dim i

	'セルの高さ合わせ
	Call ExcelSetRowHeight(MyBook, Target, 1, 13.50)
	Call ExcelSetRowHeight(MyBook, Target, 2, 24.50)
	Call ExcelSetRowHeight(MyBook, Target, 3, 13.50)
	Call ExcelSetRowHeight(MyBook, Target, 4, 24.50)
	Call ExcelSetRowHeight(MyBook, Target, 5, 20.25)

	For i = 6 To nRows + 5
		Call ExcelSetRowHeight(MyBook, Target, i, nRowHeight)
	Next

	'セルの幅合わせ
	Call ExcelSetColumnWidth(MyBook, Target, 1, 3.50)
	Call ExcelSetColumnWidth(MyBook, Target, 2, 27.00)
	Call ExcelSetColumnWidth(MyBook, Target, 3, 0.75)
	Call ExcelSetColumnWidth(MyBook, Target, 4, 15.00)
	Call ExcelSetColumnWidth(MyBook, Target, 5, 4.50)
	Call ExcelSetColumnWidth(MyBook, Target, 6, 3.00)
	Call ExcelSetColumnWidth(MyBook, Target, 7, 0.75)
	Call ExcelSetColumnWidth(MyBook, Target, 8, 13.50)
	Call ExcelSetColumnWidth(MyBook, Target, 9, 0.75)
	Call ExcelSetColumnWidth(MyBook, Target, 10, 24.00)
	Call ExcelSetColumnWidth(MyBook, Target, 11, 12.00)

End Function

' ******************************************************
' 罫線の設定
' ******************************************************
Function ExcelLine_Table(MyBook, Target)

	Dim i

	' BOX罫線
	Call ExcelRange(MyBook, Target, 1, 1, 11, nRows + 5 )
	Call ExcelBox(xlContinuous, xlMedium)

	' 上罫線
	Call ExcelRange(MyBook, Target, 1, 2, 11, 2 )
	Call ExcelLine(xlDot, xlThin)

	Call ExcelRange(MyBook, Target, 1, 3, 11, 3 )
	Call ExcelLine(xlContinuous, xlThin)

	Call ExcelRange(MyBook, Target, 1, 4, 11, 4 )
	Call ExcelLine(xlDot, xlThin)

	Call ExcelRange(MyBook, Target, 1, 5, 11, 5 )
	Call ExcelLine(xlContinuous, xlMedium)

	Call ExcelRange(MyBook, Target, 1, 6, 11, 6 )
	Call ExcelLine(xlContinuous, xlMedium)

	for i = 7 to nRows + 5
		Call ExcelRange(MyBook, Target, 1, i, 11, i )
		Call ExcelLine(xlDot, xlThin)
	Next

	' 右罫線
	Call ExcelRange(MyBook, Target, 1, 6, 1, nRows + 5 )
	Call ExcelLineRight(xlDot, xlThin)

	Call ExcelRange(MyBook, Target, 2, 1, 2, 2 )
	Call ExcelLineRight(xlContinuous, xlThin)

	Call ExcelRange(MyBook, Target, 2, 5, 2, nRows + 5 )
	Call ExcelLineRight(xlContinuous, xlThin)

	Call ExcelRange(MyBook, Target, 4, 5, 4, nRows + 5 )
	Call ExcelLineRight(xlContinuous, xlThin)

	Call ExcelRange(MyBook, Target, 5, 6, 5, nRows + 5 )
	Call ExcelLineRight(xlDot, xlThin)

	Call ExcelRange(MyBook, Target, 6, 3, 6, nRows + 5 )
	Call ExcelLineRight(xlContinuous, xlThin)

	Call ExcelRange(MyBook, Target, 8, 1, 8, 4 )
	Call ExcelLineRight(xlContinuous, xlThin)

	Call ExcelRange(MyBook, Target, 10, 1, 10, nRows + 5 )
	Call ExcelLineRight(xlContinuous, xlThin)

End Function

' ******************************************************
' セルのテキストの設定
' ******************************************************
Function ExcelSetText_Table(MyBook, Target)

	Dim i

	Call ExcelRange(MyBook, Target, 1, 1, 7, 49 )
	Call ExcelVAlign()

	' 1行目
	Call ExcelSetCell(MyBook, Target, 1, 1, " システム名")

	Call ExcelSetCell(MyBook, Target, 3, 1, " サブシステム名")

	Call ExcelSetCell(MyBook, Target, 9, 1, " テーブルID")
	Call ExcelRange(MyBook, Target, 9, 1, 10, 1 )
	Call ExcelHAlign()
	Call ExcelRange(MyBook, Target, 9, 2, 10, 1 )
	Call ExcelVAlign()

	Call ExcelSetCell(MyBook, Target, 11, 1, "ページ")
	Call ExcelRange(MyBook, Target, 11, 1, 11, 1 )
	Call ExcelHAlign()
	Call ExcelRange(MyBook, Target, 11, 2, 11, 2 )
	Call ExcelHAlign()
	Call ExcelRange(MyBook, Target, 11, 2, 11, 2 )
	Call ExcelVAlign()

	' 2行目
	Call ExcelSetCell(MyBook, Target, 11, 2, "/")
	Call ExcelRange(MyBook, Target, 11, 2, 11, 2 )

	' 3行目
	Call ExcelSetCell(MyBook, Target, 1, 3, " テーブル名")

	Call ExcelSetCell(MyBook, Target, 7, 3, "種別")
	Call ExcelRange(MyBook, Target, 7, 3, 8, 3 )
	Call ExcelHAlign()

	Call ExcelSetCell(MyBook, Target, 9, 3, "作成日")
	Call ExcelRange(MyBook, Target, 9, 3, 10, 3 )
	Call ExcelHAlign()

	Call ExcelSetCell(MyBook, Target, 11, 3, "作成者")
	Call ExcelRange(MyBook, Target, 11, 3, 11, 3 )
	Call ExcelHAlign()

	' 4行目
	Call ExcelRange(MyBook, Target, 8, 4, 8, 4 )
	Call ExcelHAlign2()
	Call ExcelVAlign()

	Call ExcelRange(MyBook, Target, 10, 4, 10, 4 )
	Call ExcelHAlign2()
	Call ExcelVAlign()

	Call ExcelRange(MyBook, Target, 11, 4, 11, 4 )
	Call ExcelHAlign2()
	Call ExcelVAlign()

	' 5行目
	Call ExcelSetCell(MyBook, Target, 1, 5, " 列名")

	Call ExcelSetCell(MyBook, Target, 3, 5, "データ型")
	Call ExcelRange(MyBook, Target, 3, 5, 4, 5 )
	Call ExcelHAlign()

	Call ExcelSetCell(MyBook, Target, 5, 5, "サイズ")
	Call ExcelRange(MyBook, Target, 5, 5, 6, 5 )
	Call ExcelHAlign()

	Call ExcelSetCell(MyBook, Target, 7, 5, " 説明")

	Call ExcelSetCell(MyBook, Target, 11, 5, "主キー")
	Call ExcelRange(MyBook, Target, 11, 5, 11, 5 )
	Call ExcelHAlign()
	Call ExcelVAlign()

	for i = 6 to nRows + 5
		Call ExcelSetCell(MyBook, Target, 1, i, i - 5)
		Call ExcelRange(MyBook, Target, 1, i, 1, i )
		Call ExcelHAlign()
		Call ExcelRange(MyBook, Target, 11, i, 11, i )
		Call ExcelHAlign()
	next

	Call ExcelRange(MyBook, Target, 1, 1, 1, 1 )

End Function

' ******************************************************
' ヘッダー,余白の指定
' ******************************************************
Function Format_Page(MyBook)

	on error resume next

	With MyBook.ActiveSheet.PageSetup
		.CenterHeader = "&18&A"
		.PaperSize = xlPaperB4
'		.LeftMargin = ExcelApp.InchesToPoints(0.393700787401575)
'		.RightMargin = ExcelApp.InchesToPoints(0.196850393700787)
'		.TopMargin = ExcelApp.InchesToPoints(0.551181102362205)
'		.BottomMargin = ExcelApp.InchesToPoints(0.393700787401575)
'		.HeaderMargin = ExcelApp.InchesToPoints(0.196850393700787)
'		.FooterMargin = ExcelApp.InchesToPoints(0.196850393700787)
	End With

	on error goto 0

End Function

' ******************************************************
' シングルクォートで囲む
' ******************************************************
Function Ss( strValue )

	Ss = "'" & strValue & "'"

End Function

' ******************************************************
' DB接続(SQLServer)
' ******************************************************
Function SQS_DBConnect( _
	Connection, _
	Server, _
	DB, _
	User, _
	Pass _
)

	Dim ConnectionString

	ConnectionString = _
		"Provider=SQLOLEDB;" & _
		"Data Source=" & Server & ";" & _
		"Initial Catalog=" & DB & ";" & _
		"User ID=" & User & ";" & _
		"Password=" & Pass & ";"
	
	if IsEmpty( Connection ) then
		Set Connection = CreateObject( "ADODB.Connection" )
	end if

	on error resume next
	Connection.Open ConnectionString
	if Err.Number <> 0 then
		SQS_DBConnect = "ERROR:" & Err.Description
	else
		SQS_DBConnect = ""
	end if
	on error goto 0

End Function

' ******************************************************
' DB終了処理(接続を閉じる)
' ******************************************************
Function DBClose( _
	CnRs _
)
	
	On Error Resume Next
	If CnRs.State >= 1 Then
		CnRs.Close
	End If
	On Error Goto 0

	DBClose = True

End Function

' ******************************************************
' DB読込み
' 【戻り値】: True(データ有り),False(データ無し)
' ******************************************************
Function DBGet( _
	Connection, _
	Record, _
	SqlQuery, _
	bUpadateFlg _
)
	if IsEmpty( Record ) then
		Set Record = CreateObject( "ADODB.Recordset" )
	end if

	Dim ConstCheck

	' 閉じていない時は閉じる
	If Record.State >= 1 Then
		Record.Close
	End If

	' 更新処理に使用する場合は、レコード単位の共有的ロック
	If bUpadateFlg Then
		ConstCheck = adLockOptimistic
		if IsEmpty( ConstCheck ) then
			Record.LockType = 3
		else
			Record.LockType = adLockOptimistic
		end if
	else
		ConstCheck = adLockOptimistic
		if IsEmpty( ConstCheck ) then
			Record.LockType = 1
		else 
			Record.LockType = adLockReadOnly
		end if
	End If
	
	' レコードセット作成
	Record.Open SqlQuery, Connection
	If Record.State >= 1 Then
		If Record.EOF Then
			DBGet = False
		Else
			DBGet = True
		End If
	else
		DBGet = False
	end if

End Function

</SCRIPT>
</JOB>


関連する記事

VBScript : Excel.Application でファイルを複数選択する




posted by lightbox at 2019-02-10 19:44 | VBS + オブジェクト | このブログの読者になる | 更新情報をチェックする

2019年02月03日


PHP で MySQLをテストする為のソースコード


※ $_GET['text'] で入力された SQL が引き渡されます。
※ GET コマンドなので、内容はアドレスバーで確認する事ができます
※ Form を使わずにアドレスバーから直接 SQL を実行できます。
( IE11 は不可 )

列(セル)の HTML の出力用に関数を作成しています。内部は『ヒアドキュメント』を利用した比較的可読性の高い方法を用いて文字列を作成しています。

ヒアドキュメント構文では、最後の識別子をインデントしてはいけないので関数内でHTML の階層を単純化するほうがメンテナンス性が高くなると思います。

QueryString に text が無い場合と text に有効な文字が全く無い場合は  show variables でシステム変数の一覧を表示します
if ( !isset( $_GET['text'] ) || trim($_GET['text']) == "" ) {
	$_GET['text'] = "show variables";
}
MySQL 改良版拡張モジュール
<?php
session_cache_limiter('nocache');
session_start();

header( "Content-Type: text/html; charset=utf-8" );

?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SQL実行結果</title> 
<style>
table {
	border: solid 1px #000;
	border-collapse: collapse;
}

th,td {
	border: solid 1px #000;
	padding: 5px;
}
</style>
</head>
<body style='white-space:pre;'>
<?php
if ( !isset( $_GET['text'] ) || trim($_GET['text']) == "" ) {
	$_GET['text'] = "show variables";
}

print $_GET['text'] . "\n";

$server = 'localhost';
$dbname = 'lightbox';
$user = 'root';
$password = 'パスワード';

// ***************************
// 接続
// ***************************
$mysqli = @ new mysqli($server, $user, $password, $dbname);
if ($mysqli->connect_error) {
	print "接続エラーです : ({$mysqli->connect_errno}) ({$mysqli->connect_error})";
	exit();
}

// ***************************
// クライアントの文字セット
// ***************************
$mysqli->set_charset("utf8"); 

// ***************************
// クエリ
// ***************************
$result = $mysqli->query($_GET['text']);
if ( !$result ) {
	print "\n";
	print "<span style='color:#f00'>error : " . $mysqli->error . "</span>";
	exit();
}

// ***************************
// 列数
// ***************************
$nfield = $result->field_count;
if ( $nfield ) {
	$ncount = 0;
	print "<table>\n";

	// 行番号用タイトル
	print "\t<th></th>";

	// 列のタイトルを作成
	$field = $result->fetch_fields( );
	for( $i = 0; $i < $nfield; $i++ ) {

		print_cell_html( "th", $field[$i]->name );

	}

	print "\n";

	// ***************************
	// 行データ
	// ***************************
	while ($row = $result->fetch_row()) {

		print "<tr>\n";
		// 行番号
		print "\t<td>" . ($ncount + 1) . "</td>";

		for( $i = 0; $i < $nfield; $i++ ) {

			print_cell_html( "td", $row[$i] );

		}
		print "\n</tr>\n";

		$ncount++;
	}

	print "</table>";
}

// ***************************
// 接続解除
// ***************************
$mysqli->close();


// ***************************
// セルの HTML 出力
// ***************************
function print_cell_html( $html, $data ) {

print <<<CELL_HTML
<{$html}>{$data}</{$html}>
CELL_HTML;

}

?>

</body>
</html>


PHP 5.5.0 で非推奨になり、PHP 7.0.0 で削除
<?php
session_cache_limiter('nocache');
session_start();

header( "Content-Type: text/html; charset=utf-8" );

?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SQL実行結果</title> 
</head>
<body style='white-space:pre;'>
<?php
print $_GET['text'] . "\n";

$server = 'localhost';
$dbname = 'lightbox';
$user = 'root';
$password = 'パスワード';

// ***************************
// 接続
// ***************************
$connect = @mysql_connect( $server, $user, $password );
if ( !$connect ) {
	print "接続エラーです";
	exit();
}

// ***************************
// DB選択
// ***************************
mysql_select_db( $dbname, $connect );
mysql_set_charset("utf8", $connect); 

// ***************************
// クエリ
// ***************************
$result = mysql_query($_GET['text'], $connect);
if ( !$result ) {
	print "\n";
	print "<span style='color:#f00'>" . mysql_error() . "</span>";
}

// ***************************
// 列数
// ***************************
$nfield = @mysql_num_fields( $result );
if ( $nfield ) {
	$ncount = 0;
	print "<table style='border:solid 1px #000;border-collapse:collapse;'>\n";

	print "\t<th style='border:solid 1px #000;padding:5px;'></th>\n";
	for( $i = 0; $i < $nfield; $i++ ) {
		$field = mysql_fetch_field( $result, $i );

		print "\t<th style='border:solid 1px #000;padding:5px;'>{$field->name}</th>\n";
	}

	while ($row = mysql_fetch_row($result)) {
		print "<tr>\n";
		print "\t<td style='border:solid 1px #000;padding:5px;'>" . ($ncount + 1) . "</td>\n";
		for( $i = 0; $i < $nfield; $i++ ) {
			print "\t<td style='border:solid 1px #000;padding:5px;'>{$row[$i]}</td>\n";
		}
		print "</tr>\n";
		$ncount++;
	}
	print "</table>";
}

// ***************************
// 接続解除
// ***************************
mysql_close($connect);
?>

</body>
</html>

※ これらのコードは、開発上のテストを目的としているのでセキュリティ上の考慮はされていません。



posted by lightbox at 2019-02-03 18:37 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2019年02月02日


PHP で ODBC 関数を使って MS Access( データベース )にアクセスして結果を JSON 文字列として出力する



db.php は簡単なクラスですが、MS Access を使用する為に SHIFT_JIS でSQL を作成する必要があります。また、戻された結果も SHIFT_JIS なので UTF-8 に変換しています。利用者は、UTF-8 ベースのソースコードから SHIFT_JIS を意識せずに処理する事が可能になります。
db.php(クラス)
<?php
// ***************************
// データベースクラス
// (このソースは UTF-8N)
//
// UTF-8 => SHIFT_JIS
// ***************************
class DB {
 
	public $connect;
	public $result;
 
// ***************************
// コンストラクタ
// ***************************
	function DB( $connect ) {

		$this->connect = odbc_connect($connect, "", "");

	}
 
// ***************************
// 接続解除
// ***************************
	function close( ) {

		odbc_close( $this->connect );

	}
 
// ***************************
// 単純クエリー( 実行 )
// ***************************
	function query( $sql_query ) {

		// SHIFT_JIS に変換
		$sql_query = mb_convert_encoding( $sql_query, "cp932", "utf-8" );

		$ret = @odbc_exec( $this->connect, $sql_query );
		return $ret;
	}
 
// ***************************
// フェッチ
// ***************************
	function fetch( $result=null ) {

		// 引数が無い場合は前回実行された 
		// $this->result を使用する
		if ( $result == null ) {
			$result = $this->result;
		}

		// ※ Invalid argument supplied for foreach()
		$error = error_reporting(E_ALL & ~E_WARNING);

		// SHIFT_JIS のデータ
		$ret1 = odbc_fetch_array( $result );
		// 空の配列
		$ret2 = array();

		// 数字をインデックスとする配列を作成する
		foreach ($ret1 as $key => $value) {
			// UTF-8 で使えるようにする
			$ret2[] = mb_convert_encoding( $value, "utf-8", "cp932" );
		}
		// 連想配列を作成する
		foreach ($ret1 as $key => $value) {
			// UTF-8 で使えるようにする
			$key = mb_convert_encoding( $key, "utf-8", "cp932" );
			$ret2[$key] = mb_convert_encoding( $value, "utf-8", "cp932" );
		}

		// 関数内での設定以前に戻す
		error_reporting($error);

		// 数字インデックスと文字列インデックスの連想配列
		return $ret2;
	}
 
// ***************************
// クエリーとフェッチ
// ***************************
	function query_ex( $sql_query='' ) {

		// 引数がある場合は、query and fetch
		if ( $sql_query != '' ) {
			$this->result = $this->query( $sql_query );
			if ( !$this->result ) {
				return false;
			}
			return $this->fetch( );
		}
		// 引数が無い場合は fetch のみ
		else {
			return $this->fetch( );
		}
 
	}

// ***************************
// 実行 : query と同じ
// ***************************
	function execute( $sql_exec ) {

		// SHIFT_JIS に変換
		$sql_exec = mb_convert_encoding( $sql_exec, "cp932", "utf-8" );

		$ret = odbc_exec( $this->connect, $sql_exec );
		return $ret;

	}
 
 
}
?>


以下は、accdb を使って( mdb でも可 )データを JSON として出力しています。

ms-access-json.php
<?php
// ***************************
// このソースは UTF-8N
// ***************************
header( "Content-Type: text/plain; Charset=utf-8" );

// ***************************
// キャッシュを使用しない
// ***************************
header( "Expires: Thu, 19 Nov 1981 08:52:00 GMT" );
header( "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0" );
header( "Pragma: no-cache" );

// ***************************
// データベースアクセスクラス
// ***************************
require_once("db.php");

// ***************************
// PHP 設定
// ***************************
mb_language( "ja" );
mb_internal_encoding("UTF-8");

// ***************************
// MS Acceess ファイル
// ***************************
$dbfile = "販売管理B.accdb";
//$dbfile = "販売管理B.mdb";

// ***************************
// ファイル名を SHIFT_JIS に変換
// ***************************
$dbfile = mb_convert_encoding( $dbfile, "cp932", "utf-8" );


// ***************************
// 接続文字列
// ODBC ドライバ名( 32ビット )
// のある場所 ▼
// HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\ODBC\ODBCINST.INI
// ***************************
$connect_string = "Provider=MSDASQL;";
$connect_string .= "Driver={Microsoft Access Driver (*.mdb, *.accdb)};";
$dbpath = realpath($dbfile);
$connect_string .= "dbq={$dbpath};";

// ***************************
// クラスのインスタンス
// ***************************
$db = new DB( $connect_string );
if ( $db->connect === false ) {
	print "接続に失敗しました : " . mb_convert_encoding( odbc_errormsg(), "utf-8", "cp932" );
	exit();
}

// ***************************
// 1) UTF-8 で SQL を作成
// ***************************
$query = <<<SQL
	select
		[社員マスタ].*,
		[社員マスタ].[社員コード] as scode
	from [社員マスタ]
	where [社員コード] in('0001','0002','0003')
SQL;

// ***************************
// データ全体用の配列
// ***************************
$json = array();

// ***************************
// クラスでクエリの実行
// ※ 初回
// ***************************
$column = $db->query_ex( $query );
if ( $column === false ) {
	print "SQLの実行に失敗しました : " . mb_convert_encoding( odbc_errormsg( $db->connect ), "utf-8", "cp932" );
	$db->close();
	exit();
}

// ***************************
// 全ての行を取得
// ***************************
while ( $column ) {

	// ***************************
	// 行単位で結果の連想配列をセット
	// ***************************
	$json['items'][] = $column;
	$column = $db->query_ex( );

};

// ***************************
// 接続解除
// ***************************
$db->close();

// ***************************
// php.exe の確認
// ***************************
if( PHP_INT_SIZE == 4 ) {
	print "PHPは 32ビットです\n";
}

// ***************************
// テストの為、見やすいオプション
// 1) 日本語をエスケープしない
// 2) 整形する
// ***************************
print json_encode( $json, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

?>


関連する Microsoft ドキュメント( 接続文字列 )

Microsoft OLE DB Provider for ODBC の概要

データ ソースにアクセスする( 接続文字列を作成する )


出力結果
PHPは 32ビットです
{
    "items": [
        {
            "0": "0001",
            "1": "浦岡 友也",
            "2": "ウラオカ トモヤ",
            "3": "0003",
            "4": "0",
            "5": "2005-09-12 00:00:00",
            "6": "2005-11-28 00:00:00",
            "7": "270000",
            "8": "9000",
            "9": "",
            "10": "0001",
            "社員コード": "0001",
            "氏名": "浦岡 友也",
            "フリガナ": "ウラオカ トモヤ",
            "所属": "0003",
            "性別": "0",
            "作成日": "2005-09-12 00:00:00",
            "更新日": "2005-11-28 00:00:00",
            "給与": "270000",
            "手当": "9000",
            "管理者": "",
            "scode": "0001"
        },
        {
            "0": "0002",
            "1": "山村 洋代",
            "2": "ヤマムラ ヒロヨ",
            "3": "0003",
            "4": "1",
            "5": "2005-06-17 00:00:00",
            "6": "2005-09-18 00:00:00",
            "7": "300000",
            "8": "",
            "9": "",
            "10": "0002",
            "社員コード": "0002",
            "氏名": "山村 洋代",
            "フリガナ": "ヤマムラ ヒロヨ",
            "所属": "0003",
            "性別": "1",
            "作成日": "2005-06-17 00:00:00",
            "更新日": "2005-09-18 00:00:00",
            "給与": "300000",
            "手当": "",
            "管理者": "",
            "scode": "0002"
        },
        {
            "0": "0003",
            "1": "多岡 冬行",
            "2": "タオカ フユユキ",
            "3": "0002",
            "4": "0",
            "5": "2005-08-14 00:00:00",
            "6": "2005-11-14 00:00:00",
            "7": "250000",
            "8": "",
            "9": "",
            "10": "0003",
            "社員コード": "0003",
            "氏名": "多岡 冬行",
            "フリガナ": "タオカ フユユキ",
            "所属": "0002",
            "性別": "0",
            "作成日": "2005-08-14 00:00:00",
            "更新日": "2005-11-14 00:00:00",
            "給与": "250000",
            "手当": "",
            "管理者": "",
            "scode": "0003"
        }
    ]
}

32 ビット ODBC の一覧をレジストリエディタで開く

strParam = "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\ODBC\ODBCINST.INI"

' レジストリ書き込み用
Set WshShell = CreateObject( "WScript.Shell" )
' WMI用
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

' レジストリエディタが最後に開いていたキーの登録を行います
strPath = "Software\Microsoft\Windows\CurrentVersion\Applets\Regedit\LastKey"
if GetOSVersion() >= 6 then
	strRegPath = "コンピューター\" & strParam
else
	strRegPath = "マイ コンピュータ\" & strParam
end if

' 既に regedit が実行中の場合はいったん終了させます
Set colProcessList = objWMIService.ExecQuery _ 
	("Select * from Win32_Process Where Name = 'regedit.exe'") 
For Each objProcess in colProcessList
	' 最後のウインドウの位置とサイズを保存する為の終わらせ方
	WshShell.AppActivate("レジストリ エディタ")
	Wscript.Sleep(500)
	WshShell.SendKeys ("%{F4}")
	Wscript.Sleep(500)
	' 上記終わらせ方が失敗した時の強制終了
	on error resume next
	objProcess.Terminate() 
	on error goto 0
Next 

WshShell.RegWrite "HKCU\" & strPath, strRegPath, "REG_SZ"

' レジストリエディタを起動します
Call WshShell.Run( "regedit.exe" )
' レジストリエディタが終わるまで待つ場合は以下のようにします
' Call WshShell.Run( "regedit.exe", , True )

REM **********************************************************
REM OS バージョンの取得
REM **********************************************************
Function GetOSVersion()

	Dim colTarget,str,aData,I,nTarget

	Set colTarget = objWMIService.ExecQuery( _
		 "select Version from Win32_OperatingSystem" _
	)
	For Each objRow in colTarget
		str = objRow.Version
	Next

	aData = Split( str, "." )
	For I = 0 to Ubound( aData )
		if I > 1 then
			Exit For
		end if
		if I > 0 then
			nTarget = nTarget & "."
		end if
		nTarget = nTarget & aData(I)
	Next

	GetOSVersion = CDbl( nTarget )

End Function




posted by lightbox at 2019-02-02 17:52 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2019年02月01日


VBScript : ファイルのフルパスをクリップボードへ( ダブルクォートなし )

エクスプローラで、SHIFT キーを押しながら右クリックすると『パスとしてコピー』がありますが、ダブルクォートが付加されています( たいていはそのほうがいいのですが )ので、ダブルクォートのないパスを取得します


▼ こんな感じで取得されます
"C:\Program Files\7-Zip\7-zip.dll"

filepath.vbs( SendTo ディレクトリに置いてください )

Set WshShell = Wscript.CreateObject("WScript.Shell")
Set Fso = Wscript.CreateObject("Scripting.FileSystemObject")

strTemp = WshShell.ExpandEnvironmentStrings("%temp%")
strPath = strTemp & "\__clipCommand.tmp"

Set objHandle = Fso.OpenTextFile( strPath, 2, True )
objHandle.Write Wscript.Arguments(0)

Call WshShell.Run( "cmd.exe /c clip < """ & strPath & """", 0, True )
▼ こうなります
C:\Program Files\7-Zip\7-zip.dll

以下はディレクトリ部分を省いた名前の部分のみをクリップボードにコピーします。

filename.vbs( SendTo ディレクトリに置いてください )

Set WshShell = Wscript.CreateObject("WScript.Shell")
Set Fso = Wscript.CreateObject("Scripting.FileSystemObject")

strTemp = WshShell.ExpandEnvironmentStrings("%temp%")
strPath = strTemp & "\__clipCommand.tmp"

Set objHandle = Fso.OpenTextFile( strPath, 2, True )
strName = Wscript.Arguments(0)
aPath = Split(strName,"\")
strName = aPath(Ubound(aPath))
objHandle.Write strName

Call WshShell.Run( "cmd.exe /c clip < """ & strPath & """", 0, True )

▼ こうなります
7-zip.dll

さらに以下では、複数ファイルを選択した場合のファイル名部分だけを取り出して複数行としてコピーします( 但しあまり大量のファイルは元々の文字列の制限によりエラーとなります

filelist.vbs( SendTo ディレクトリに置いてください )

Set WshShell = Wscript.CreateObject("WScript.Shell")
Set Fso = Wscript.CreateObject("Scripting.FileSystemObject")

str = ""
For I = 0 to Wscript.Arguments.Count-1
	aData = Split( Wscript.Arguments(I), "\" )
	str = str & aData(Ubound(aData)) & vbCrLf
Next

strTemp = WshShell.ExpandEnvironmentStrings("%temp%")
strPath = strTemp & "\__clipCommand.tmp"

Set objHandle = Fso.OpenTextFile( strPath, 2, True )
objHandle.Write str
Call WshShell.Run( "cmd.exe /c clip < """ & strPath & """", 0, True )

▼ ファイルが多すぎて起きるエラー


▼ うまくいくとこんな感じです
nslookup.exe
ntdll.dll
odbc32.dll
ole32.dll


操作補足

エクスプローラで SendTo フォルダに移動するには、アドレスバーに sendto と直接入力します。テンポラリフォルダは、%temp% と入力して下さい。




コードを直接ダウンロードした場合は、右クリックのプロパティより『許可する』にチェックしておきます。


結果の文字列の前後に任意の文字列を追加したい場合

filepath.vbs

Wscript.Arguments(0) が目的の文字列なので、この前後に任意の文字列を追加します。
Set WshShell = Wscript.CreateObject("WScript.Shell")
Set Fso = Wscript.CreateObject("Scripting.FileSystemObject")

strTemp = WshShell.ExpandEnvironmentStrings("%temp%")
strPath = strTemp & "\__clipCommand.tmp"

Set objHandle = Fso.OpenTextFile( strPath, 2, True )
objHandle.Write "`" & Wscript.Arguments(0) & "`"

Call WshShell.Run( "cmd.exe /c clip < """ & strPath & """", 0, True )


filelist.vbs

aData(Ubound(aData)) が一つのファイル名なので、この前後に任意の文字列を追加します。
Set WshShell = Wscript.CreateObject("WScript.Shell")
Set Fso = Wscript.CreateObject("Scripting.FileSystemObject")

str = ""
For I = 0 to Wscript.Arguments.Count-1
	aData = Split( Wscript.Arguments(I), "\" )
	str = str & "これは" & aData(Ubound(aData)) & "です" & vbCrLf
Next

strTemp = WshShell.ExpandEnvironmentStrings("%temp%")
strPath = strTemp & "\__clipCommand.tmp"

Set objHandle = Fso.OpenTextFile( strPath, 2, True )
objHandle.Write str
Call WshShell.Run( "cmd.exe /c clip < """ & strPath & """", 0, True )






posted by lightbox at 2019-02-01 11:47 | 右クリックで「送る」 | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します
container 終わり



フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり