PowerBuilderのソースファイル(ライブラリ/PBLファイル)は、独自形式のためPowerBuilder IDE上でしか開くことができません。
しかし、PowerBuilderが提供する組み込み関数の中には、ソースファイルの内容を解析し登録されているオブジェクトの一覧を取得したり、本体部分をテキストとして取得したりする機能が含まれているので、中身を取り出しテキスト化すること自体は可能そうです。
今回は、この機能を使ってPBL形式のソースファイルをテキスト形式のソースファイルとして一括エクスポートするツールを作成しました。
Windows 10上にVB6の開発環境を構築する必要があり作業を行ったのですが、そのときいろいろな問題が発生しました。
インターネット上には、Windows 10へVB6をインストールための様々な情報が公開されていますが、実際に試してみると公開されている情報と違う箇所や端折れる手順などがありました。
今回、実際に行った一連の作業を記事にまとめました。
※注意
Visual Basic 6.0は、開発元のMicrosoftのサポートが終了した開発環境です。
最悪の場合、システムやデータに復旧不可能なダメージを与える可能性があります。
実際の導入にあたっては細心の注意を払い、ご自身の責任においてお試し下さい。
ゲームボーイミクロはとても小さくガジェット好きの心をつかんで離さないゲーム機ですが、ゲームボーイアドバンスSPやDS/3DSシリーズと違い、液晶画面がむき出しの状態なので画面に傷がつかないか常にひやひやします。
もともとは専用の布ポーチが付属しており、持ち運びや保管はポーチに入れて画面を保護するようになっていたのですが、今となっては入手が困難。
じゃあ代わりのものを…と探してみても、ミクロがぴったり収まるサイズのケースというのがなかなか見つからないんですよね。
なかば諦めかけていたのですが…
ついに見つけました!
100円ショップ『ザ・ダイソー』で買い物をしているとき、スマホのアクセサリーを扱うコーナーで「イヤホンケース」なるものを発見。
見た瞬間、その大きさにピーンときました。
早速買い求めてミクロを収納してみたところ、「ミクロ用に作ったのではないか!?」と思うくらいピッタリ!
ちょっとピッタリすぎるかなという感じも若干しますが、傷が付いたり塗装が剥げたりすることはなさそうです。
そこそこの強度がありそうな素材で作られているので、カバンの中で”つぶれ”や”こすれ”には強そうです。
試す勇気はありませんが、落下もある程度までは耐えてくれそうな感じがします。
網ポケットの部分にイヤフォンを収納した状態でもきちんとファスナーがしまりました。
商品名は『イヤホンケース&小物入れ(角形)』、型番は”K-18P-12”、”002”のようです。
色は3色くらいありました。
価格は税別100円です。
Windows 10のWSL向けに最適化されたという触れ込みの新しいLinuxディストリビューション『WLinux』がWindowsストアで公開されました。
さっそく購入してみたのですが、起動した瞬間、いきなりのエラー。
「WslRegisterDistribution failed with error: 0x80070003」と表示され、表示されたメッセージに従いキーを押すと終了してしまいました。
萎えます。
この現象を回避する方法が分かったので、記述します。
Windowsの設定を開き(Windowsキー + “i”の同時押しが便利です)、[システム]-[ストレージ]-[新しいコンテンツの保存先を変更する]画面で表示される、[新しいアプリの保存先]の設定値を確認してください。
この設定値がCドライブ以外に設定されていると「WslRegisterDistribution failed with error: 0x80070003」と表示されてしまうようです。
「Cドライブ」に変更した後、適用ボタンを押して設定を反映します。
「新しいアプリの保存先」に「Cドライブ」以外を設定した状態でWLinuxをインストールしている場合、いったんWLinuxをアンインストールします。
アンインストールした後、WLinuxを再度インストールを行い起動すると先ほどのようにエラーが表示されず次のフェーズへと進めるようです。
お客様から「Excelのメニュー項目の表示が英語になってしまった」と問い合わせをいただきました。
最初は、Excelの設定画面([ファイル]-[オプション]-[言語])で「表示言語の選択」の設定が変わってしまい英語表記になってしまったのかと思ったのですが、現地で調査をしてみるとどうも勝手が違うようです。
マイクロソフトのコミュニティを調べてみると同じような現象の報告がありました。「Excel2016の英語設定を日本語に変更する方法をお教えください。(サーフェスラップトップ)」
ここに書かれているようにWindowsの表示言語の設定(設定の[時刻と言語]-[地域と言語]-[言語])などを確認しましたが、Windowsの設定は「日本語」で問題がありません。
Windows Updateもすべて正常に行われているようです。
ダメもとでWindowsに言語を追加してみたり、Windowsの表示言語をいったん日本語以外の言語に切り替えて、日本語に戻してみたりしましたがExcelの表記は英語のままです。
もう一度マイクロソフトのコミュニティに投稿された情報をよく読むと重要な情報を見つけました。
しかし、ストアアプリ版Officeなので、Windowsの表示言語と連動していて、画像のように、言語を追加できないようになっています。
問題を起こしたパソコンのExcelの設定画面を確認してみると、表示言語を切り替えるための項目が表示されていないことがわかりました。
インストールされているものはストアアプリ版のOfficeのようです。
ちなみに、デスクトップ版Excel 2016の設定画面は下記のような表示になります。
「表示言語の選択」という項目で表示言語とヘルプ言語の設定や、追加の言語リソースの取得(言語パック)ができるようになっています。
さらに、確認をするとネットワークの接続が不安定だったようでインターネットにうまく接続できない状態があったようです。
Windowsの『ストア』で「ダウンロードと更新」の状況を確認すると、Office系のアプリがダウンロードの途中でエラーになって保留状態になっていました。
保留状態になっているものを手動で更新し、更新が完了したところでExcelを立ち上げてみると…
ストアアプリの更新に失敗したのが原因のようです。
パソコンのメーカーや導入した時期なども関係していた
今回の問題が起きたパソコンはデル社製のデスクトップマシンで2018年3月に導入したパソコンだったのですが、ここに落とし穴がありました。
デルのWebサイトで公開されているナレッジベース情報に「Office 2016 プリインストール版 アクティベーション方法(Windows 10)」という項目があります。
ここに以下に引用する記載があります。
導入した時期が2018年3月なので、Fall Creators Updateが適用されたWindows 10 が導入されています。
Fall Creators Updateが適用されたパソコンのプレインストール(PIPC) Office 2016なのでストアアプリ版Officeが導入されていたようです。
ストアアプリ版のOfficeなんてSurfaceだけかと思ったら、ほかのメーカーのパソコンにも入っていたとは…
今回はじめて知りました。
PORTABOOKにWindows 10 April 2018 Update(バージョン 1803、ビルド番号 17134)をインストールしました。
ストレージが32GBと非常に少ないPORTABOOKなのでオンラインでアップデートというわけにはいきませんが、USBメモリを2本用意し一本をインストールメディアもう一本をテンポラリとするいつもの方法でアップデートすることができました。
(PORTABOOK(XMC10)にWindows 10 Creators Update(Ver. 1703)を入れる方法 を参照)
SmartGWTのフォーム上で任意スケールの数値入力を行うためのコンポーネントが用意されていなかったので作成しました。
このコンポーネントは、SmartGWTのcom.smartgwt.client.widgets.form.fields.TextItemクラスを拡張して実装しています。
setLengthメソッドで全体の桁数を設定します。
桁数には、入力された文字数そのもので評価され、符号や小数点などもカウントされるので注意が必要です。
setDecimalPadメソッドで小数点以下の桁数を設定します。
getValueメソッド、またはgetValueAsBigDecimalメソッドで入力された結果をBigDecimal型で取得します。
BigDecimal型への変換は、setDecimalPadメソッドで指定された小数点以下の桁数、setRoundingModeメソッドで指定された丸め方法で変換されます。
入力されたテキストが数値としてパースできなかった場合は、nullが返ります。
動作確認を行った環境:
Java SE Development Kit 7
// This software is distributed under the license of NYSL. // ( http://www.kmonos.net/nysl/ ) package com.ria_lab.gwt.smartgwt.client.ui.form; import java.math.BigDecimal; import java.math.RoundingMode; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.i18n.client.NumberFormat; import com.smartgwt.client.data.Record; import com.smartgwt.client.widgets.form.DynamicForm; import com.smartgwt.client.widgets.form.FormItemValueFormatter; import com.smartgwt.client.widgets.form.FormItemValueParser; import com.smartgwt.client.widgets.form.fields.FormItem; import com.smartgwt.client.widgets.form.fields.TextItem; /** * SmartGWTの com.smartgwt.client.widgets.form.DynamicForm で * 数値型(java.math.BigDecimal)を入力するためのコンポーネント */ public class BigDecimalItem extends TextItem { /** */ private Integer scale; /** */ private RoundingMode roundingMode = RoundingMode.DOWN; /** */ private NumberFormat format; /** */ private FormItemValueFormatter formatter = new FormItemValueFormatter() { @Override public String formatValue(Object value, Record record, DynamicForm form, FormItem item) { if (value == null) { return ""; } try { return asBigDecimal(value.toString(), scale, roundingMode).toString(); } catch (NumberFormatException e) { return value.toString(); } } }; /** */ private FormItemValueParser parser = new FormItemValueParser() { @Override public Object parseValue(String value, DynamicForm form, FormItem item) { if (value == null || value.trim().isEmpty()) { return null; } try { BigDecimal decimal = asBigDecimal(value.toString(), scale, roundingMode); return format == null ? decimal : format.format(decimal); } catch (NumberFormatException e) { return value; } } }; /** * Constructor * */ public BigDecimalItem() { super(); init(); } /** * Constructor * * @param jsObj */ public BigDecimalItem(JavaScriptObject jsObj) { super(jsObj); init(); } /** * Constructor * * @param name */ public BigDecimalItem(String name) { super(name); init(); } /** * Constructor * * @param name * @param title */ public BigDecimalItem(String name, String title) { super(name, title); init(); } /** * */ private void init() { setEditorValueFormatter(formatter); setValueFormatter(formatter); setEditorValueParser(parser); setKeyPressFilter("[0-9\\-\\+\\.]"); } /** * @see com.smartgwt.client.widgets.form.fields.FormItem#setDecimalPad(java.lang.Integer) */ @Override public void setDecimalPad(Integer decimalPad) { if (decimalPad != null && decimalPad < 0) { throw new IllegalArgumentException(); } super.setDecimalPrecision(decimalPad); scale = decimalPad; format = getNumberFormat(decimalPad); } /** * @return roundingMode */ public RoundingMode getRoundingMode() { return roundingMode; } /** * @param roundingMode roundingMode */ public void setRoundingMode(RoundingMode roundingMode) { if (roundingMode == null) { throw new IllegalArgumentException(); } this.roundingMode = roundingMode; } /** * @see com.smartgwt.client.widgets.form.fields.FormItem#getValue() */ @Override public Object getValue() { return getValueAsBigDecimal(); } /** * * @return */ public BigDecimal getValueAsBigDecimal() { String s = getValueAsString(); if (s == null || s.trim().isEmpty()) { return null; } try { return asBigDecimal(s, scale, roundingMode); } catch (NumberFormatException e) { return null; } } /** * * @param s * @param scale * @param roundingMode * @return */ private static BigDecimal asBigDecimal(String s, Integer scale, RoundingMode roundingMode) { return scale == null ? new BigDecimal(s) : new BigDecimal(s).setScale(scale, roundingMode); } /** * * @param scale * @return */ private static NumberFormat getNumberFormat(Integer scale) { if (scale == null) { return NumberFormat.getFormat("0"); } StringBuffer sb = new StringBuffer(scale == 0 ? "#0" : "#0."); for (int i = 0; i < scale; i++) { sb.append("0"); } return NumberFormat.getFormat(sb.toString()); } }
PORTABOOKにWindows 10 Fall Creators Update(バージョン1709、ビルド番号16299)をインストールしてみました。
基本的な流れは、Windows 10 Creators Update(バージョン1703、ビルド番号15063)の時と同じく、USBメモリを2つ用意して、ひとつをインストールメディア、もうひとつをテンポラリとしてインストールを進めます。
Windows 10 Creators Updateのときはインストールメディアとして使うUSBメモリの容量が4GB以上だったのに対し、Windows 10 Fall Creators Updateでは8GB以上のUSBメモリが必要になっているので注意が必要です。
具体的な手順については、過去の記事を参照してください。
PORTABOOK(XMC10)にWindows 10 Creators Update(Ver. 1703)を入れる方法
インストールメディア作成の開始からWindowsの起動ができるまでの所要時間は、だいたい4時間弱でした。
Windows 10 Fall Creators Updateのインストール前に、本体ストレージにインストールしたソフトをいったん削除し、9.3GB程度の空き領域を確保した状態でインストール作業を始めました。
Windows 10 Fall Creators Updateインストール直後の空き容量は、4.7GB程度です。
MicrosoftのDBサーバ『SQL Server』に、Microsoft純正のJDBCドライバを用いてJavaから接続した際のハマりメモ。
下記のようなメッセージが表示された人向けです。
ホスト 192.168.1.XXX、ポート 55378 への TCP/IP 接続が失敗しました。エラー: “接続のタイムアウト: 詳細情報なし。接続プロパティを調べて、SQL Server のインスタンスがホスト上で実行されていて、ポートへの TCP/IP 接続が許可されており、そのポートへの TCP 接続がファイアウォールにブロックされていないことを確認してください。”。
ユーザー ‘ユーザ名‘ はログインできませんでした。 ClientConnectionId:XXXXXXXXXX-XXXX-XXXXXXXXX
とりあえずの結論は、「SQL Serverの『名前付きインスタンス』と『TCP動的ポート』、ファイアウォールの設定を確認する」です。
きちんと検証はしていませんが、Accessにリンクテーブルを作ろうとした際、ODBCでも同様の現象が発生しました。
この記事に記載した内容を確認・設定しJDBC接続できるようにしたあとで、ODBC接続を試みたら難なく接続することができました。ODBC経由でSQL Serverに接続できない問題が起きているかたも、この記事の内容が役に立つと思います。
コントロールパネルの『サービス』から確認する。
起動していない場合は、SQL Server Browserサービスを起動する。
(その他、SQL Server関連のサービスも起動されていることを確認する。これを忘れて少しハマりました。)
詳細は、Microsoftのサイトの『SQL Server Browserサービス』を参照。
SQL Serverへの接続に必要なポートが開放されているか、(主にSQL Serverが稼働しているリモートマシンの)ファイアウォールなどの設定を確認する。
JDBCの接続URLの記法により、必要な開放ポートが変わるので注意。
// この部分 Connection con = DriverManager.getConnection("jdbc:sqlserver://192.168.1.XXX:55378;instanceName=SQLEXPRESS;databaseName=データベース名", "ユーザ名", "パスワード";
ポート番号 1434とインスタンスがリッスンしているポート番号が開放されているか確認
ポート番号 1434とインスタンスがリッスンしているポート番号が開放されているか確認
インスタンスがリッスンしているポート番号が開放されているか確認
URL記法の詳細は『接続URLの構築』、開放ポートの詳細は『インターネットを介しての SQL Server への接続』を参照
URLの中にユーザ名やパスワードを持たせた場合、java.sql.DriverManager#getConnection(String url)も使える。
PostgreSQLなどをJDBCを介して使っていると、つい接続URLに”jdbc:sqlserver://192.168.1.XXX:インスタンスがリッスンしているポート番号\\インスタンス名;databaseName=データベース名”みたいな書き方をしてしまいますが、これが受け付けてもらえず例外が発生しLocalizedMessageプロパティには「ポート番号 1433\SQLEXPRESS は無効です。」というようなメッセージが設定されます。(ErrorCodeプロパティには0、SqlStateプロパティにはnullが設定されていました)
SQL Server構成マネージャーを起動し、『SQL Serverネットワークの構成』からSQL Serverのインスタンスを選択し、一覧表示されたプロトコルから『TCP/IP』を選択。
プロパティを表示し、『IP All』の『TCP動的ポート』に設定されている値を確認する。
SQL Server構成マネージャーは、スタートメニューの検索ボックスで「sqlservermanager12.msc」とか「sqlservermanager13.msc」とか打ち込むと表示される。
されない場合は、\Windows\SysWOW64のフォルダあたりを探す。
そもそもSQL Serverがリモート接続可能な状態で動いているか、TCP/IPで接続可能になっているかなども確認が必要です。
詳細は『構成マネージャー』を参照
Windows 10上で稼働しているSQL Server 2014 Expressに、リモートのMacから接続して検証。
Mac側のJava環境はJava SE 7(1.7.0_51)、JDBCドライバは『Microsoft JDBC Driver 6.0 for SQL Server』のJDBC 4.1版を使用。
// This software is distributed under the license of NYSL. // ( http://www.kmonos.net/nysl/ ) import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import com.microsoft.sqlserver.jdbc.SQLServerException; public class Test { public static void main(String[] args) { // 名前付きインスタンス"SQLEXPRESS"上のデータベースに接続する際のJDBCの接続URL // ポート1434とTCP動的ポートの開放が必要 String url = "jdbc:sqlserver://192.168.1.XXX\\SQLEXPRESS;databaseName=データベース名"; // ポート1434とTCP動的ポートの開放が必要 // String url = "jdbc:sqlserver://192.168.1.XXX;instanceName=SQLEXPRESS;databaseName=データベース名"; // TCP動的ポートの開放が必要 // String url = "jdbc:sqlserver://192.168.1.XXX:55378;instanceName=SQLEXPRESS;databaseName=データベース名"; // SQL Serverのユーザ名とパスワード String username = "ユーザ名"; String password = "パスワード"; try { // JDBCドライバをロード Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); // SQL Serverに接続 Connection con = DriverManager.getConnection(url, username, password); // SQL Serverに問い合わせ Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("select * from 適当なテーブル"); while (rs.next()) { System.out.println(rs.getString("テーブルの適当な項目")); } // 後処理 rs.close(); stmt.close(); con.close(); } catch (SQLServerException e) { // SQL Server固有の例外 System.out.println("ERROR-CODE:\t" + e.getErrorCode()); System.out.println("SQL-STATE:\t" + e.getSQLState()); System.out.println("MESSAGE:\t" + e.getLocalizedMessage()); e.printStackTrace(); } catch (Exception e) { // その他の例外 e.printStackTrace(); } } }
Apache Hive上に登録されているすべてのテーブルをAccessのリンクテーブルとして一括登録するプログラムです。
前提として、Apache HiveのODBCドライバが導入済み、ODBC接続設定が完了している必要があります。
プログラム実行中に既にAccess上に登録済みのテーブルが出現した場合、リンクテーブルの更新は行わず、処理をスキップします。
更新を必要とする場合は、処理前に該当するAccess上のテーブルを削除してから処理を行ってください。
プログラム中のコメントとしても記述していますが、連続してリンクテーブルの追加処理を行っていると、1802回目の追加処理(TableDefs.Appendの呼び出し)で「実行エラー ‘3146’: ODBC–呼び出しが失敗しました。」というエラーが発生します。
復旧させるためには、いったんAccessを終了させ、Accessを再起動、データベースを開きなおすのがもっとも早いと思います。
Hive用としていますが、ODBC接続できるPostgreSQLやMySQLなどのRDBMSであれば、接続文字列部分のDriver部分に適切な値を変更することでHive以外のデータベースのリンクテーブル登録プログラムとしても使えると思います。
動作確認を行った環境:
Access 2013 / Windows 10 Pro バージョン:1703 ビルド:15063
Microsoft Hive ODBC Driver 2.01.05.1006 / Hortonworks Hive ODBC Driver 2.01.07.1010
2.8.1
2.3.0
PostgreSQL 9.6.3
' ' This software is distributed under the license of NYSL. ' ( http://www.kmonos.net/nysl/ ) Option Explicit Option Compare Database ' ======================================================================== ' ' 指定されたHiveデータベース上のテーブルをAccessのリンクテーブルとして ' 登録するAccess VBAモジュール ' ' ' ※注意 ' 実行前に[ツール]-[参照設定]メニューで「Microsoft Active X Data Object 6.0 Library」などの ' ライブラリを参照できるようにチェックすること。 ' ' Hive側のテーブル数が1802以上の場合、1802回目のCurrentDb.TableDefs.Appendの ' 処理で「実行エラー '3146': ODBC--呼び出しが失敗しました。」が発生 ' する。(Office 2013で確認) ' ' ======================================================================== Sub ConnectHiveTables() Dim hiveCs As String Dim adoCon As ADODB.Connection Dim adoRs As ADODB.Recordset Dim accessTableName As String Dim daoTableDef As DAO.TableDef Dim sourceTableName As String ' ODBC経由でHiveに接続するための接続文字列を設定 hiveCs = "DSN=ODBC_HIVE;Driver=Microsoft Hive ODBC Driver;UID=;PWD=;" ' Hiveに接続 Set adoCon = New ADODB.Connection adoCon.Open (hiveCs) ' Hive上のテーブル情報を取得 Set adoRs = adoCon.OpenSchema(adSchemaTables) Do While Not adoRs.EOF ' Access上のテーブル名を決定 accessTableName = adoRs.Fields("TABLE_SCHEMA") & "_" & adoRs.Fields("TABLE_NAME") ' Access上にテーブルが存在するかチェックし、存在する場合は処理を飛ばす If DCount("[Name]", "MSysObjects", "[Name] = '" & accessTableName & "'") = 1 Then Debug.Print "Skip" & vbTab & accessTableName GoTo NextTable End If ' リンクテーブルの接続先となるHive上のテーブル名を決定 sourceTableName = adoRs.Fields("TABLE_SCHEMA") & "." & adoRs.Fields("TABLE_NAME") ' リンクテーブルを作成 Set daoTableDef = CurrentDb.CreateTableDef(accessTableName) With daoTableDef .Connect = "ODBC;" & hiveCs .sourceTableName = sourceTableName End With CurrentDb.TableDefs.Append daoTableDef Debug.Print "Append" & vbTab & accessTableName & vbTab & "(source='" & sourceTableName & "')" NextTable: adoRs.MoveNext DoEvents Loop adoRs.Close adoCon.Close End Sub