
番外:JavaScript版 Oracle SQLツールのコメントで
EXCELへの出力を行っているのですが、
それじゃあ、EXCELマクロを実行出来ないかと
試行してみました。
そうすると、ORACLEの検索ロジックをVBAで隠蔽できますよね
(Visual Basic Editorにパスワードをかける)
ただ、Application.Runした後、JavaScript側からは制御できなくなるので、
失敗しても、表示できないという課題はあります。(私には解決できない!今のところ)
**(HTML)**************************************************************
<html>
<head>
<title>SQL_Oracle</title>
<script type="text/javascript" src="MACRO_ORA.js"></script>
</head>
<body>
<form name="selbox">
<select name="tableName" onchange="Excel_open(this)">
<option value="none">▼選択してください</option>
<option value="MST_ADRS1">都道府県マスタ </option>
<option value="MST_ADRS2">市区町村マスタ </option>
<option value="MST_ADRS3">町字マスタ </option>
</select>
</form>
</body>
</html>
**(MACRO_ORA.js)******************************************************
function Excel_open(obj){
var idx = obj.selectedIndex;
var tblName = obj.options[idx].value;
if (idx==0) { return; }
var myMacro = "D:/TEST/MACRO_ORA.xlsm";
var excel = new ActiveXObject("Excel.Application");
excel.DisplayAlerts = false;
excel.Workbooks.Open(myMacro,0,"true");
var myD = new Date() ;
document.getElementById("labelMsg").innerText = tblName + "_"
+ myD.getFullYear() + "-"
+ (myD.getMonth()+1) + "-"
+ myD.getDate() + ".xlsx を作成しました。";
excel.Visible = true;
excel.Application.Run("ORA_SEL",tblName);
excel.Quit();
excel = null;
excel.Visible = false;
}
**(MACRO_ORA.xlsm)****************************************************
Option Explicit
Declare Function SetCurrentDirectory Lib "kernel32" Alias _
"SetCurrentDirectoryA" (ByVal CurrentDir As String) As Long
Sub ORA_SEL(ByVal myTbl As String)
Dim adoCn As ADODB.Connection
Dim adoRs As ADODB.Recordset
Dim i As Long: i = 1 ' 行
Dim j As Integer: j = 1 ' 列
Dim strDSN As String: strDSN = ThisWorkbook.Path & "\" & "TESTDB.dsn"
Dim strSQL As String: strSQL = "SELECT * FROM " & myTbl & " ORDER BY 1"
Dim strFil As String: strFil = ThisWorkbook.Path & "\" & myTbl & "_" & Date$
SetCurrentDirectory ThisWorkbook.Path
Set adoCn = New ADODB.Connection
Set adoRs = New ADODB.Recordset
Sheets(1).Select
adoCn.Open " FileDSN=" & strDSN & ";UID=TESTUSER;PWD=TESTPWD;"
adoRs.Open strSQL, adoCn, adOpenStatic, adLockReadOnly
Range("A2").CopyFromRecordset adoRs
For i = adoRs.Fields.Count To 1 Step -1
j = i - 1
Cells(1, i).Value = adoRs.Fields(j).Name
If adoRs.Fields(j).Type = 135 Then
Columns(i).Select
Selection.NumberFormatLocal = "yyyy/mm/dd;@"
Selection.HorizontalAlignment = xlCenter
End If
Next i
Range(Cells(1, 1), Cells(1, adoRs.Fields.Count)).Select
Selection.Font.Bold = True
Selection.Font.ThemeColor = xlThemeColorDark1
Selection.Interior.ColorIndex = 32
Selection.EntireColumn.AutoFit
Range(Selection, Selection.End(xlDown)).Select
Selection.Borders.LineStyle = xlContinuous
Range("A2").Select
adoRs.Close
Set adoRs = Nothing
adoCn.Close
Set adoCn = Nothing
Worksheets(1).Move
ActiveWorkbook.SaveAs fileName:=strFil, FileFormat:=xlWorkbookDefault
ActiveWorkbook.Close
ThisWorkbook.Saved = False
If Workbooks.Count <= 1 Then Application.Quit
ThisWorkbook.Close
Exit Sub
End Sub
EXCELへの出力を行っているのですが、
それじゃあ、EXCELマクロを実行出来ないかと
試行してみました。
そうすると、ORACLEの検索ロジックをVBAで隠蔽できますよね
(Visual Basic Editorにパスワードをかける)
ただ、Application.Runした後、JavaScript側からは制御できなくなるので、
失敗しても、表示できないという課題はあります。(私には解決できない!今のところ)
**(HTML)**************************************************************
<html>
<head>
<title>SQL_Oracle</title>
<script type="text/javascript" src="MACRO_ORA.js"></script>
</head>
<body>
<form name="selbox">
▼EXCEL展開するORACLE(TABLE)
<select name="tableName" onchange="Excel_open(this)">
<option value="none">▼選択してください</option>
<option value="MST_ADRS1">都道府県マスタ </option>
<option value="MST_ADRS2">市区町村マスタ </option>
<option value="MST_ADRS3">町字マスタ </option>
</select>
<label id="labelMsg"></albel>
</form>
</body>
</html>
**(MACRO_ORA.js)******************************************************
function Excel_open(obj){
var idx = obj.selectedIndex;
var tblName = obj.options[idx].value;
if (idx==0) { return; }
var myMacro = "D:/TEST/MACRO_ORA.xlsm";
var excel = new ActiveXObject("Excel.Application");
excel.DisplayAlerts = false;
excel.Workbooks.Open(myMacro,0,"true");
var myD = new Date() ;
document.getElementById("labelMsg").innerText = tblName + "_"
+ myD.getFullYear() + "-"
+ (myD.getMonth()+1) + "-"
+ myD.getDate() + ".xlsx を作成しました。";
excel.Visible = true;
excel.Application.Run("ORA_SEL",tblName);
excel.Quit();
excel = null;
excel.Visible = false;
}
**(MACRO_ORA.xlsm)****************************************************
Option Explicit
Declare Function SetCurrentDirectory Lib "kernel32" Alias _
"SetCurrentDirectoryA" (ByVal CurrentDir As String) As Long
Sub ORA_SEL(ByVal myTbl As String)
Dim adoCn As ADODB.Connection
Dim adoRs As ADODB.Recordset
Dim i As Long: i = 1 ' 行
Dim j As Integer: j = 1 ' 列
Dim strDSN As String: strDSN = ThisWorkbook.Path & "\" & "TESTDB.dsn"
Dim strSQL As String: strSQL = "SELECT * FROM " & myTbl & " ORDER BY 1"
Dim strFil As String: strFil = ThisWorkbook.Path & "\" & myTbl & "_" & Date$
SetCurrentDirectory ThisWorkbook.Path
Set adoCn = New ADODB.Connection
Set adoRs = New ADODB.Recordset
Sheets(1).Select
adoCn.Open " FileDSN=" & strDSN & ";UID=TESTUSER;PWD=TESTPWD;"
adoRs.Open strSQL, adoCn, adOpenStatic, adLockReadOnly
Range("A2").CopyFromRecordset adoRs
For i = adoRs.Fields.Count To 1 Step -1
j = i - 1
Cells(1, i).Value = adoRs.Fields(j).Name
If adoRs.Fields(j).Type = 135 Then
Columns(i).Select
Selection.NumberFormatLocal = "yyyy/mm/dd;@"
Selection.HorizontalAlignment = xlCenter
End If
Next i
Range(Cells(1, 1), Cells(1, adoRs.Fields.Count)).Select
Selection.Font.Bold = True
Selection.Font.ThemeColor = xlThemeColorDark1
Selection.Interior.ColorIndex = 32
Selection.EntireColumn.AutoFit
Range(Selection, Selection.End(xlDown)).Select
Selection.Borders.LineStyle = xlContinuous
Range("A2").Select
adoRs.Close
Set adoRs = Nothing
adoCn.Close
Set adoCn = Nothing
Worksheets(1).Move
ActiveWorkbook.SaveAs fileName:=strFil, FileFormat:=xlWorkbookDefault
ActiveWorkbook.Close
ThisWorkbook.Saved = False
If Workbooks.Count <= 1 Then Application.Quit
ThisWorkbook.Close
Exit Sub
End Sub
HTMLアプリケーションというスクリプト言語があって、
HTML+JavaScript でアプリーションの様に動かせる(ダブルクリックで)と
いうことを知りました。(知らなかった)
簡単に言うと、拡張子をHTAにすればいいということで
やってみました。↓
(また、見栄えも少し工夫してみました。)
ActiveXの警告メッセージが出ません。
エラーの場合、どこでどんなエラーかがメッセージされます。←デバッグしやすい。
でも、それだけでは、やっぱりソースの隠蔽は出来ないので、
コンパイルはないのかと探していると
Vectorに、HTABOXクイックという
圧縮EXEを利用したユティリティを発見。
完全ではないですが、これだと一般ユーザーなら(僕にも一時出力は見付けられず)
ほぼソース展開は無理でしょう。
ただ、フリーソフト不可の環境ではやはり難しいでしょうか!
**(ORA_XLSOUT.HTA)**********************************************************
<html>
<head>
<meta http-equiv="content-type"
content="text/html; charset=shift_jis">
<hta:application
applicationName="ORACLE EXCEL OUT"
contextmenu="no"
scroll="no">
</hta:application>
<title>ORACLE EXCEL OUT</title>
<script type="text/javascript"><!--
function func_xlsOut(obj) {
var idx = obj.selectedIndex;
if (idx==0) { return; }
var tblName = obj.options[idx].value;
var sqlStr = "SELECT * FROM " + tblName + " ORDER BY 1";
var cn = new ActiveXObject("ADODB.Connection");
cn.Open(" Driver={Microsoft ODBC for Oracle};CONNECTSTRING=ORCL;UID=TESTUSER;PWD=TESTPWD;");
try {
var rs = cn.Execute(sqlStr);
} catch (e) {
alert("SQLの実行が失敗しました");
cn.Close
return ;
}
var sh = new ActiveXObject("WScript.Shell");
var myD = new Date();
var xlsFile = sh.CurrentDirectory + "" + tblName + "_"
+ myD.getFullYear() + "-"
+ ( "0" + (myD.getMonth()+1)).slice( -2 ) + "-"
+ ( "0" + myD.getDate()).slice( -2) + ".xlsx";
alert(xlsFile + "\nに出力します");
var excel = new ActiveXObject("Excel.Application");
var book = excel.Workbooks.Add(); // 新規ワークブックを作成
var sheet = book.WorkSheets(1); // シートを取得
var j = 1;
for (var i=0; i<rs.Fields.Count; i++) {
j = i + 1;
sheet.Cells(1,j).value = rs.Fields(i).name;
if (rs.Fields(i).Type == 135) {
sheet.Columns(j).NumberFormatLocal = "yyyy/mm/dd;@";
sheet.Columns(j).HorizontalAlignment = -4108; // 中央寄せ
}
}
var k = 1;
while (!rs.EOF){
k = k + 1;
for (var i=0; i<rs.Fields.Count; i++) {
j = i + 1;
if (rs(i).value == null) {
// 何もしない
} else if (rs.Fields(i).Type == 135) {
sheet.Cells(k,j).value = dateEdit( rs(i).value );
} else {
sheet.Cells(k,j).value = rs(i).value;
}
}
rs.MoveNext();
}
var range = sheet.Range(sheet.Cells(1,1),sheet.Cells(1,i));
range.Font.Bold = true;
range.Font.ColorIndex = 2; // 白
range.Interior.ColorIndex = 32; // 青
range = sheet.Range(sheet.Cells(1,1),sheet.Cells(k,i));
range.Borders.Weight = 2; // 罫線(細線)
range.Borders.LineStyle = 1; // 罫線(実線)
sheet.Columns.AutoFit();
excel.Visible = true; // ブックを保存
excel.DisplayAlerts = false; // 既存ファイルがあっても上書き
book.SaveAs(xlsFile);
excel.DisplayAlerts = true;
excel.Quit(); // Excelを閉じて終了
excel = null;
rs.Close();
cn.Close();
rs = null;
cn = null;
alert(xlsFile + "\nに出力しました");
document.getElementById("labelMsg").innerText = xlsFile + "\nに出力しました";
}
// 日付形式編集
function dateEdit(myDate) {
var buff = new Date( myDate );
buff = buff.toLocaleString();
buff = buff.replace("年","/");
buff = buff.replace("月","/");
buff = buff.replace("日","");
return buff;
}
// --></script>
<style type="text/css"><!--
body {
background-color: #00ff00;
color: #ffffff;
filter: progid:DXImageTransform.Microsoft.Gradient
(GradientType="0", StartColorStr="#000000", EndColorStr="#00ff00");
font-family: "メイリオ";
}
--></style>
</head>
<body>
<form name="selbox">
<p>▼EXCEL展開するORACLE(TABLE)</p>
<table><tr valign="TOP"><td>
<select name="tableName" onchange="func_xlsOut(this)">
<option value="none">▼選択してください</option>
<option value="MST_ADRS1">都道府県マスタ </option>
<option value="MST_ADRS2">市区町村マスタ </option>
<option value="MST_ADRS3">町字マスタ </option>
</select></td><td width=25></td><td width=480>
<p><label id="labelMsg"></albel></p></td></tr>
</table>
</form>
<script type="text/javascript"><!--
window.resizeTo(650, 225);
// --></script>
</body>
</html>
なので、↑前回コメントのTABLE指定の全件版を改良して
御馴染のSQL(SELECT)実行版を作ってみました。
ちょっと遅いですが・・・、動くことは動きます。
もう、種が無くなって来ました。トホホ
**(ORA_SQLEXEC.hta)***************************************************
<html>
<head>
<meta http-equiv="content-type"
content="text/html; charset=shift_jis">
<hta:application
applicationName="ORACLE SQL EXEC"
contextmenu="no"
scroll="no">
</hta:application>
<title>ORACLE SQL EXEC</title>
<script type="text/javascript"><!--
function func_execSQL() {
var mySQL = document.myForm.sql.value;
if (mySQL == "") { alert("SQLを入力して下さい"); return; }
mySQL = mySQL.toUpperCase();
if (mySQL.slice(0,6) != "SELECT") { alert("SQLは、SELECTのみでお願いします"); return; }
var myFil = document.myForm.file.value;
if (myFil == "") { alert("出力するEXCELファイル名を\n入力して下さい"); return; }
var sh = new ActiveXObject("WScript.Shell");
var xlsFil = sh.CurrentDirectory + "" + myFil + ".xlsx";
if (confirm("SQLの実行結果を\n" + xlsFil + "\nに出力します。OKですか?") == false) { return; }
document.getElementById("labelMsg").innerText = "処理中です";
var cn = new ActiveXObject("ADODB.Connection");
cn.Open("Driver={Microsoft ODBC for Oracle};CONNECTSTRING=ORCL;UID=TESTUSER;PWD=TESTPWD;");
try {
var rs = cn.Execute(mySQL);
} catch (e) {
alert("SQLの実行が失敗しました");
document.getElementById("labelMsg").innerText = "SQLの実行が失敗しました";
cn.Close
return ;
}
var excel = new ActiveXObject("Excel.Application");
var book = excel.Workbooks.Add(); // 新規ワークブックを作成
var sheet = book.WorkSheets(1); // シートを取得
var j = 1;
for (var i=0; i<rs.Fields.Count; i++) {
j = i + 1;
sheet.Cells(1,j).value = rs.Fields(i).name;
if (rs.Fields(i).Type == 135) {
sheet.Columns(j).NumberFormatLocal = "yyyy/mm/dd;@";
sheet.Columns(j).HorizontalAlignment = -4108; // 中央寄せ
}
}
var k = 1;
while (!rs.EOF){
k = k + 1;
for (var i=0; i<rs.Fields.Count; i++) {
j = i + 1;
if (rs(i).value == null) {
// 何もしない
} else if (rs.Fields(i).Type == 135) {
sheet.Cells(k,j).value = dateEdit( rs(i).value );
} else {
sheet.Cells(k,j).value = rs(i).value;
}
}
rs.MoveNext();
}
var range = sheet.Range(sheet.Cells(1,1),sheet.Cells(1,i));
range.Font.Bold = true;
range.Font.ColorIndex = 2; // 白
range.Interior.ColorIndex = 32; // 青
range = sheet.Range(sheet.Cells(1,1),sheet.Cells(k,i));
range.Borders.Weight = 2; // 罫線(細線)
range.Borders.LineStyle = 1; // 罫線(実線)
sheet.Columns.AutoFit();
excel.Visible = true; // ブックを保存
excel.DisplayAlerts = false; // 既存ファイルがあっても上書き
book.SaveAs(xlsFil);
excel.DisplayAlerts = true;
excel.Quit(); // Excelを閉じて終了
excel = null;
rs.Close();
cn.Close();
rs = null;
cn = null;
alert(xlsFil + "\nに出力しました");
document.getElementById("labelMsg").innerText = xlsFil + "\nに出力しました";
}
// 日付形式編集
function dateEdit(myDate) {
var buff = new Date( myDate );
buff = buff.toLocaleString();
buff = buff.replace("年","/");
buff = buff.replace("月","/");
buff = buff.replace("日","");
return buff;
}
// --></script>
<style type="text/css"><!--
body {
background-color: #ff0000;
color: #ffffff;
filter: progid:DXImageTransform.Microsoft.Gradient
(GradientType="1", StartColorStr="#000000", EndColorStr="#ff0000");
font-family: "メイリオ";
}
.fstyle1 input { font-family: "HGゴシックM"; }
.fstyle2 { font-size:10pt; }
--></style>
</head>
<body>
<form name="myForm">
<table valign="TOP">
<tr><td></td><td>▼実行するSQL(SELECT)</td></tr>
<tr><td>SQL</td>
<td><textarea name="sql" rows="10" cols="54"></textarea></td></tr>
<tr><td>FILE</td>
<td><div class="fstyle1"><input type="text" name="file" value="" style="width:30em;"></div></td></tr>
<tr><td valign="TOP"><input type="button" value="検索" onClick="func_execSQL()"></td>
<td><font class="fstyle2"><label id="labelMsg"></albel></font></td></tr>
</table>
</form>
<script type="text/javascript"><!--
window.resizeTo(480, 330);
// --></script>
</body>
</html>
テーブルリストを起動時に自動で取得。
**(ORA_XLSOUT.HTA)*********************
<html>
<head>
<meta http-equiv="content-type"
content="text/html; charset=shift_jis">
<hta:application
applicationName="ORACLE TBL OUT"
contextmenu="no"
scroll="no">
</hta:application>
<title>ORACLE TBL OUT</title>
<script type="text/javascript"><!--
function func_xlsOut(obj) {
document.getElementById("labelMsg").innerText = "";
var idx = obj.selectedIndex;
if (idx==0) { return; }
var tblName = obj.options[idx].value;
var strSql = "SELECT * FROM " + tblName + " ORDER BY 1";
var sh = new ActiveXObject("WScript.Shell");
var myD = new Date();
var xlsFile = sh.CurrentDirectory + "" + tblName + "_"
+ myD.getFullYear() + "-"
+ ( "0" + (myD.getMonth()+1)).slice( -2 ) + "-"
+ ( "0" + myD.getDate()).slice( -2) + ".xlsx";
if (confirm(xlsFile + "\nに出力します。OKですか?") == false) { return; }
document.getElementById("labelMsg").innerText = "処理中";
var cn = new ActiveXObject("ADODB.Connection");
cn.Open("Driver={Microsoft ODBC for Oracle};CONNECTSTRING=ORCL;UID=TESTUSER;PWD=TESTPWD;");
try {
var rs = cn.Execute(strSql);
} catch (e) {
alert("SQLの実行が失敗");
cn.Close;
return ;
}
var excel = new ActiveXObject("Excel.Application");
var book = excel.Workbooks.Add();
var sheet = book.WorkSheets(1);
var j = 1;
var k = 2;
while (!rs.EOF){
k = k + 1;
for (var i=0; i<rs.Fields.Count; i++) {
j = i + 1;
if (rs(i).value == null) {
// 何もしない
} else if (rs.Fields(i).Type == 135) {
sheet.Cells(k,j).value = dateEdit( rs(i).value );
} else {
sheet.Cells(k,j).value = rs(i).value;
}
}
rs.MoveNext();
}
sheet.Columns.AutoFit();
var strSql2;
for (var i=0; i<rs.Fields.Count; i++) {
j = i + 1;
sheet.Cells(1,j).value = rs.Fields(i).name;
if (rs.Fields(i).Type == 135) {
sheet.Columns(j).NumberFormatLocal = "yyyy/mm/dd;@";
sheet.Columns(j).HorizontalAlignment = -4108;
}
strSql2 = "SELECT COMMENTS FROM USER_COL_COMMENTS WHERE TABLE_NAME = '"
+ tblName + "' AND COLUMN_NAME = '" + rs.Fields(i).name + "'";
var rs2 = cn.Execute(strSql2);
sheet.Cells(2,j).value = rs2(0).value;
rs2.Close();
rs2 = null;
}
var range = sheet.Range(sheet.Cells(1,1),sheet.Cells(1,i));
range.Font.Bold = true;
range.Font.ColorIndex = 2;
range.Interior.ColorIndex = 32;
var range = sheet.Range(sheet.Cells(2,1),sheet.Cells(2,i));
range.Interior.ColorIndex = 15;
sheet.Rows(2).RowHeight = 0;
range = sheet.Range(sheet.Cells(1,1),sheet.Cells(k,i));
range.Borders.Weight = 2;
range.Borders.LineStyle = 1;
excel.Visible = true;
excel.DisplayAlerts = false;
book.SaveAs(xlsFile);
excel.DisplayAlerts = true;
excel.Quit();
excel = null;
rs.Close();
cn.Close();
rs = null;
cn = null;
alert(xlsFile + "\nに出力しました");
document.getElementById("labelMsg").innerText = xlsFile + "\nに出力しました";
}
function dateEdit(myDate) {
var buff = new Date( myDate );
buff = buff.toLocaleString();
buff = buff.replace("年","/");
buff = buff.replace("月","/");
buff = buff.replace("日","");
return buff;
}
function func_tblList() {
var strSql = "SELECT TABLE_NAME,COMMENTS FROM USER_TAB_COMMENTS ORDER BY TABLE_NAME";
var cn = new ActiveXObject("ADODB.Connection");
cn.Open("Driver={Microsoft ODBC for Oracle};CONNECTSTRING=ORCL;UID=TESTUSER;PWD=TESTPWD;");
try {
var rs = cn.Execute(strSql);
} catch (e) {
cn.Close;
document.write('検索対象テーブル検索不能');
alert("検索対象テーブル検索不能");
return ;
}
document.write('<form name="selbox">');
document.write('<p>▼EXCEL展開するORACLE(TABLE)</p>');
document.write('<table><tr valign="TOP"><td>');
document.write('<select name="tableName" onchange="func_xlsOut(this)">');
document.write('<option value="none">▼選択してください</option>');
while (!rs.EOF){
document.write('<option value="' + rs(0).value + '">' + rs(1).value + '</option>');
rs.MoveNext();
}
document.write('</select></td><td width=25></td><td width=480>');
document.write('<p><label id="labelMsg"></albel></p></td></tr></table></form>');
rs.Close();
cn.Close();
rs = null;
cn = null;
}
// --></script>
<style type="text/css"><!--
body {
background-color: #00ff00;
color: #ffffff;
filter: progid:DXImageTransform.Microsoft.Gradient
(GradientType="0", StartColorStr="#000000", EndColorStr="#00ff00");
}
--></style>
</head>
<body>
<script type="text/javascript"><!--
window.resizeTo(650, 225);
func_tblList();
// --></script>
</body>
</html>