カテゴリー: Webノウハウ

ウェブサイトやブログの構築・運用に役立つ記事

  • ACCESS VBA 複合機(コピー機)のグレースケール印刷指定方法

    ■複合機側でグレースケール印刷を標準設定しているのに、ACCESSでレポート印刷する際、初期設定のカラー印刷に戻っている。そのたびに設定操作が面倒だ。
     
     [ACCESS VBAによる指定方法]
     
      該当レポートのページフォーマットイベントに以下のコードを追加。

      Private Sub Report_Page()
            Me.Printer.ColorMode = acPRCMMonochrome
      End Sub

     
     [説明]
     
      最近はカラーインクの経費削減で、黒インクのみの印刷が多くなりました。複合機ドライバーのプロパティ設定でグレースケール印刷を標準設定にしています。Word文書、Excel文書等の印刷では、グレースケール印刷出来ていますが、ACCESSのレポート印刷では、カラー印刷になってしまいます。ACCESSでは、なぜか複合機の標準設定は反映されないようです。そこで、上記のようなコードを追加すると、グレースケール印刷のコントロールができるようになりました。
      
      以上、ご参考まで。
     

  • canvasについて続編2―ミウラ折りのデモ

     何年か前、「スマホを2本指でスワイプすると、文字と画像が大きくできる。だけど、画面全体は元のサイズなので、端の方が途切れてしまう。画面も大きくなるようにできないものか。」というような会話をしました。

     ややあって、その会話と、何かで見た宇宙ステーションの発電パネルが宇宙空間で広がっていく映像とが私の頭の中で混ざってしまいました。宇宙ステーションの発電パネルは、打ち上げ時には小さく折りたたまれており、宇宙に飛び出て、ほとんど一瞬の間に、いっぱいに広がります。この折り方は、発案者三浦公亮氏の名前を採って「ミウラ折り」と呼ばれています。

     ミウラ折りは、下図の各辺で折り曲げる折り方です。各辺では折り曲げるけれど、各平行四辺形の内部では折り曲げません。そして、谷折りと山折りをうまく組み合わせることで、ほとんど瞬時に閉じたり開いたりできるのです。

         
       

     

     上図は、広げた状態の図ですが、右下の小さな赤丸の近くをクリックすると、少しだけ折った状態の図になります。そのまま、左ボタンを押したままマウスカーソルを動かすと、閉じたり開いたりできます。

     また、右側にある「軌跡の表示」ボタンをクリックすると、赤丸マークの動く軌跡が表示できます。これは、直線でも円でもありません(双曲線の一部ではなかろうかと思いますが、未確認です)。

     右下の「手動⇒自動」ボタンをクリックすると、閉じたり開いたりの動作を自動的に繰り返し表示するようになります。

     上図には、3×3=9枚のパネルが表示されています。左側に表示した縮小図の当該位置をクリックすることで、表示するパネルを2×3、3×2、あるいは2×2にすることができます。枚数が多すぎて複雑になって見づらい場合などに活用してください。

     もし動かない場合は、タイトル「canvasについて続編2―ミウラ折りのデモ」をクリックして単独表示にしてみてください。

    (これは、「canvasについて」の続編です。)

  • canvasについて続編―詰将棋をちゃんと動くようにしてみた

    canvasについて」に描いた詰将棋を、実際に動くようにしてみました。

    おかげでHTMLとJavascriptについて、大変勉強になりました。canvasを3枚重ねて使っているのですが、下手をすると、下にある「一覧表示 ▶︎ Webノウハウ, スタッフの日記, ブログ」とある箱まで重なってしまって、何やらわからないことになってしまうのに苦労しました。

     

    上図の駒をマウスでドラッグすると、将棋のルールに則って、動かすことができます。ぜひ、やってみてください。

    もし動かない場合は、タイトル「canvasについて続編―詰将棋をちゃんと動くようにしてみた」をクリックして単独表示にしてみてください。

    なお、canvasを重ねて使う方法については、けーちゃんのプログラム開発ノート【JavaScript】 Canvasでレイヤーを表現する(https://note.affi-sapo-sv.com/js-canvas-layer.php)を参考にさせていただきました。

     

     

  • canvasについて

    HTML5のcanvasについて調べてみました。

    それで、やあっとこんなことができるようになりました。

    上の枠内で、マウスのボタンを押しながら、マウスを動かしてみてください。 をクリックしてからやると、色が付きます。

    次に、詰将棋とかをやってみようと思い、絵は描くことができました。しかし、今回は、動作は断念しました。だから下図で「金」をドラッグしても、何も出ません。

    いろいろ研究してみれば、もっといろんなことができそうです。

    ただ、いちいち script を書かないといけないのが、ちょっと煩わしいです。

     

  • 「ャtト」って、こういうことだったんだ

     ネット上で時々見る意味不明の言葉「ャtト」について、ひょんなことから判明したので、ここに記しておくことにします。

     まず、その「ひょんなこと」について。
     現在開発中のシステムで、「予算実績管理表」というものをpdf出力するテストを行いました。ファイル名は、“予算実績管理表_~.pdf”としたつもりでした(「~」の部分は補足情報)。ところが、“落Z実績管理廟~.pdf”なるファイルができてしまいました。“予”が“落”、“算”が“Z”、“表_”が“廟”に文字化けしてしまった形です。
     ネットを探しても、対処方法が分からず、文字の順序を変えたり、前後に他の文字を入れたりすると、ということをいろいろ試してみて、ついに、“予”の後ろと“表”の後ろに“\”を入れると、期待した正しいファイル名になることが判明しました。

     「文字“表”の後ろに“\”」で、思い出したことがあります。
     かなり昔、ソースプログラムの“表”という文字の後ろには“\”を付けないと、文字化けしたり、コンパイルエラーになってしまったりというコンパイラがありました。
     これは、“表”という文字のShift-JISでのコードが「955c(16進表示)」で、2バイト目が「5c」つまり“\”と同じなので、エスケープ文字(“\n”(改行)などとして使われるもの)と判断されてしまうからです。そこで、“\”+「文字」の機能の一つである、「“\\”が“\”という文字1文字を表す」ということを利用します。つまり、“表”という文字の2バイト目がエスケープ文字の“\”、その後ろにさらに“\”を付けることによって、“\\”となり、「“\”という文字1文字」となって、最終的に“表\”は“表”となり、また、後続の文字もちゃんと正しく処理される訳です。

     そこで、“予”についても、2バイト目が「5c」なのではないかと調べました。その通りでした。
     さらに、2バイト目が「5c」のものを探してみると、“ソ”(835c)がありました。
     もし、“ソ”についても同様の文字化けが起き、“\”を付けると文字化けしないなら、文字化けの原因はこれであり、他の文字も、2バイト目が“\”だったらその後ろに“\”を追加することで、文字化けを防ぐことができると考えられます。
     そして、“ソ”を含む文字列として、“ソフトウェア”を用いることにして、実験。

     その実験結果のファイル名を見て、声を上げてしまいました。
     実験が成功したからでも、失敗したからでもありません。
     “ャtトウェア”となったからです(“ャ”は小さいカタカナ、拗音)。
     この、あちこちのサイトで見かける意味不明な文字列。ファイルをダウンロードするとファイル名中に見られることのある意味不明な文字列。ついに、その意味が、分かったからです。

     “ソ”は「835c」、“フ”は「8374」、「5c」がエスケープ文字“\”とみなされると、次の文字「83」あるいは「8374」は“\n”とかの“\”と組み合わせて特別な意味になる文字でないので、この“\”は無視されてしまい、「83 83 74」となります。「8383」は“ャ”、「74」は“t”なので、結果として、“ャtトウェア”となる訳です。

     おまけ。
     今回のきっかけとなった“予算”と“表_”については、
       予=975c、算=8e5a、結果として「97 8e 5a」=落Z
       表=955c、_=5f、結果として「95 5f」=廟
    となってしまっていました。
     対処としては、

      $fileName = mb_convert_encoding($fileName, "SJIS-WIN");

      header('Content-Disposition: attachment;filename="'.$fileName.'"');

    の間に、

      $fileName = str_replace('\\', '\\\\', $fileName);

    を入れました。“'\\'”とあるのは、“\”1つの意味。“'\'”としてしまうと“'”の意味になってしまいます。

  • Azure SQLSEREVR <-> Windows10 ACCESS.accdb VPN接続で動作確認

    はじめに
      Windows2008R2サーバー、Windows7の2020年1月サポート終了に伴い、自社サーバーのOSアップグレードを検討していたのですが、せっかくなので、Microsoft Azureへの移行を検討してみました。要件としては、現行のC/SシステムにおけるSQLSERVERとAccessクライアントの処理が、 Cloud上のSQLSEREVER – VPN接続 – Accessクライアントで実現できる事、です。 これが出来れば、インターネット経由で自宅パソコンやモバイル端末から接続して仕事ができるので便利です。

    Azure移行イメージ

    Azure移行イメージ

      目次
    1.無料アカウントを作り、仮想サーバー(Windows2016+SQLSERVER)を構築
    2.仮想サーバーでVPN接続設定
    3.仮想サーバー内SQLSERVERの外部接続設定
    4.クライアントのSSMSで仮想サーバーSQLSERVERの接続確認
    5.Access.accdb用のODBC設定

     

     1.無料アカウントを作り、仮想サーバー(Windows2016+SQLSERVER)を構築
       自分のようなお試しユーザ向けのAzure無料アカウントを作り、Azureポータルにログイン。
    ポータル画面は、直観的に何となくクリックして進めていく事ができます。
    よくわからない設定があっても、その都度リンクされたヘルプサイトを見て確認する事ができました。 自分は、仮想サーバーの構築をMicrosoftのDocサイトを参考にしました。
     
      クイックスタート:Azure ポータルでWindows仮想マシンを作成する(Microsoft.comに移動)
      https://docs.microsoft.com/ja-jp/azure/virtual-machines/windows/quick-create-portal
     
      作成後、RDP接続で仮想サーバーに接続。まず、作成直後の仮想サーバーは英語なので、サーバーの日本語化設定をして、 その後、仮想サーバーのブラウザを使ってSQLSERVER2016及び管理ソフト(SSMS)をインストールしました。

    仮想サーバ構築後
    仮想サーバ構築後

     2.仮想サーバーでVPN接続設定
      仮想サーバーと自宅のパソコンを接続する形態をAzureでは「ポイント対サイトVPN接続」と呼ぶらしい。 設定は、
     
      ネイティブAzure 証明書認証を使用したVNetへのポイント対サイト接続の構成:Azureポータル(Microsoft.comに移動)

    https://docs.microsoft.com/ja-jp/azure/vpn-gateway/vpn-gateway-howto-point-to-site-resource-manager-portal
     を参考にしました。

    【ネットワークトラフィック許可の設定】
      受信ポートの追加設定は特になし。仮想ネットワークに接続している事が前提になるので、この設定で問題なし。

    ネットワークトラフィック許可の設定
    ネットワークトラフィック許可の設定

    パソコンで上記のサイトの説明に従ってVPN構成設定を行い、接続確認。

    VPN接続画像
    VPN接続画像

     3.仮想サーバー内SQLSERVERの外部接続設定
      仮想サーバーのFireWallで、1433のポートを受信許可。セキュリティが心配なら、ローカルIPアドレス、リモートIPアドレス、 プロファイル指定も行います。
     
      [START]-[セキュリティが強化されたWindowsファイヤーウォール]-[受信の規則]-[新しい規則]

    受信の規則の設定1
    受信の規則の設定1

    受信の規則の設定2
    受信の規則の設定2

    受信の規則の設定3
    受信の規則の設定3

      Sql Server Configuration Manager(構成管理)で、以下の設定を行います。
      [SQL Serverネットワークの構成]-[SQLEXPRESSのプロトコル]-[TCP/IP]-[プロパティ]
      IPALLの設定で、TCPポートに1433を設定します。


    Sql Server Configuration Manager(構成管理)
    Sql Server Configuration Manager(構成管理)

     4.クライアントのSSMSで仮想サーバーSQLSERVERの接続確認
      ここで接続確認できれば、ODBC接続も問題なしです。

    SSMSで接続確認
    SSMSで接続確認

     4.Access.accdb用のODBC設定
      最後にACCESSからSQLSERVERのテーブルをリンク接続する為に必要なODBC接続の設定を行います。
     
      ファイルDSNの設定例
      [ODBC]
    DRIVER=SQL Server Native Client 11.0
    UID=SQLSERVERログインユーザID
    WSID=DESKTOP-XXXXXXX
    APP=Microsoft Office 2013
    SERVER=192.168.1.4,1433

     

    おわりに
      とりあえず、VPN接続して動作確認はできました。サーバ―レスポンスも思ったより早いです。
      処理にもよるのでしょうが、今後は5G通信も始まるのでレスポンスについては問題にならないと思いました。セキュリティ面は、レンタルサーバーを借りて設定するよりも、はるかに堅牢なシステム構築が簡単に出来そうです。
     
      さて、気になる利用料金ですが、Azure 料金計算ツール
    https://azure.microsoft.com/ja-jp/pricing/calculator/
    でシミュレーションができます。試しに計算してみると・・・・・・・

    うーん、小規模システムで運用するにはちょっと掛かりすぎの利用料金でした・・・・・。費用対効果として「効果」の部分を積極的に考えていかないと割に合いません。結局自社サーバー(オンプレミス)に落ち着きそうです。

  • ドメイン名に“_”(アンダースコア)を使ってはいけない

     ドメイン名にアンダースコアが含まれていると、ブラウザからサーバリクエストをした際に、ドメイン宛てのCookieの送信がブロックされてしまう。
     
     参照:[PRB] Internet Explorer セキュリティ修正プログラム MS01-055 のインストール後、セッション変数が要求間で保持されない
     
     
     以上はInternet Explorerにおける振る舞いですが、RFC952の仕様ではホスト名の命名規則にアンダースコアは 含まれていないので、使ってはだめでした。 
     
     今回はテスト環境でハマったのですが(そもそもテスト環境でしか起こりえない。本番では正式なドメイン名になるので)、テスト環境だからとりあえず「何でもいいや」という気持ちで、分かりやすくしたいからアンダースコアを含めたドメイン名を設定しました。よくプログラムのコーディングで、変数名にアンダースコアを使うのでそんな延長で気軽に付けてしまったが為に、半日悩んでしまいました。


     また、例えば"localhost"、"testserver" 等、セカンドレベルドメイン(.coとか)、トップレベルドメイン(.jpとか)が無かったり、いわゆるFQDN形式に沿っていないと、やはりcookie送信がブロックされてしまいました。(Internet Explorer調べ)
    架空であってもそれらしい名前を設定しておく事ですね。
     
     確か過去にも同じ痛い目にあったはずなのに・・・。戒めを込めて記録しておきます。

  • MS-Wordで「図形」で絵を描いてWebページにしたら絵が見えない!

     私は、技術研究と趣味と脳の老化防止のために、Webサイトを作ってます。

     そのサイトに、MS-Wordで作ったWebページを公開したら、一生懸命描いた絵が、まるっきり見えなくなるし、後ろの方は何行も空白が続くしで、かなり焦ってしまいました。とりあえず、絵は見えるようになったし、後ろの空白も無くせたので、後のために記録を残しておこうと思います。

    1.何をやったのか。

     1-1.MS-Wordで、「図形」を使って絵を描きました。

     1-2.これを「ファイル」の「名前を付けて保存」で、「Webページ」として保存。

     1-3.保存した結果をMicrosoft Edgeで読んでみる。なんと!。絵が無くて、前後の文は表示されて、後ろはずっと空白。

     

    2.どこがいけなかったか、試行錯誤。全部書くと大変なことになるので、うまく行ったことだけ書くことにする。

     2-1.「名前を付けて保存」で「ツール(L) ▼」に気づく。「▼」をクリックしてみる。

     2-2.「Webオプション(W)」とあるので、クリックしてみると、Webオプション設定ウィンドウが。下から2行目の「VMLを使ってグラフィックスをブラウザーに表示する」が怪しい。

     2-3.「VML云々」のチェックを外して保存してみる。

     2-4.Microsoft Edgeで読んでみると、めでたしめでたし。

     なお、この絵は、テストおよびこのブログへの投稿用に作ったものです。私のサイトの問題のページは下記です。

    囲碁を開集合による位相数学で説明してみる

  • jQueryを使って、EnterキーでTab移動する

    はじめに

    システム開発の際、GUIの要件の1つに、「入力項目は、Enterキーで確定し、次の入力項目に移動すること」を挙げている事が、経験として結構あります。Webシステムにおいても、例外では無くて、以前からあった方法として、Javascriptのコーディングで
    event.keyCodeプロパティを、強制的にEnterキー(13)からTabキー(9)に入れ替えてしまう方法があります。

    if (event.keyCode == 13){
        event.keyCode = 9;
    }
    

    但し、InternetExpoler Ver.9以降は、event.keyCodeプロパティの強制的な変更が出来なくなっており、 (セキュリティ対策と思われる)この方法は使えません。

    そこで、どうしたものか?Google先生に聞いてみると、どうやらjQueryを使うと出来るらしいという事で、次のサイト「[jQuery] Enterキーでフォーカスを移動するには」を、参考にさせていただきまして、自分用にカスタマイズした関数「fEnterChangeTab()」を紹介します。

    1.関数の仕様
    ・input要素の中で、button型、hidden型、readonly属性、disabled属性は、タブ移動先から除外する事。
    ・画面最後のinput要素でEnterキーを押されたら、最初のinput要素に移動する事。
    ・画面最初のinput要素でEnterキー+Shiftキーを押されたら、最後のinput要素に移動する事。

    2.javascriptコーディング例

    // ①jQueryの取り込み
    <script type="text/javascript" src="(パス)/jquery-1.10.2.js"></script>
    
    <script type="text/javascript">
    <!--
    // input項目をEnter キー、Shift+Enterキーでtab移動 without(button, hidden) 
    function fEnterChangeTab(){	
    
      // ② input要素の選択。但し、ボタンとhidden型は除く。
      var oObject = "#Div要素のid :input:not(:button):not(:hidden)";
    	
      $(oObject).keypress(function(e) { 
        var c = e.which ? e.which : e.keyCode; // クロスブラウザ対応
        if (c == 13) {  
            var index = $(oObject).index(this); // indexは0~
            var cNext = "";
            var nLength = $(oObject).length;
            for(i=index;i<nLength;i++){
                cNext = e.shiftKey ? ":lt(" + index + "):last" : ":gt(" + index + "):first";
                // ③ 止まってはいけいない属性 readonly
                if ($(oObject + cNext).attr("readonly") == "readonly") {
                    if (e.shiftKey) index--; // 1つ前
                    else index++;            // 次へ
                }
                // ③ 止まってはいけいない属性 disabled
                else if ($(oObject + cNext).prop("disabled") == true) {
                    if (e.shiftKey) index--; // 1つ前
                    else index++;            // 次へ
                }
                else break;
            }
            if (index == nLength - 1) {
                if (! e.shiftKey){
                    // 最後の項目なら、最初に移動。
                    cNext = ":eq(1)";
                }
            }
            if (index == 0) {
                if (e.shiftKey) {
                    // 最初の項目なら、最後に移動。
                    cNext = ":eq(" + (nLength - 1) + ")";
                }
            }
            $(oObject + cNext).focus();           
            //e.defaultPrevented; ⇒ 2018.06.28 このプログラミングは間違い。
            e.preventDefault()    //規定の動作をキャンセルするため、こちらのメソッドを呼ぶ。
        }  
      }); 
    } 
    
    // ④onloadのタイミングでこの関数を実行
    if(window.attachEvent){
        // IE用
        window.attachEvent('onload',fEnterChangeTab);
    }
    else if (window.opera){
        // opera用
        window.addEventListener('load',fEnterChangeTab,false);
    }
    else {
        // Mozilla用
        window.addEventListener('load',fEnterChangeTab,false);
    }
    // -->
    </script>
    
    

    [説明]
    ① jQueryの取り込み
    (パス)は適宜、環境に置き換えて下さい。jQueryはなるべく最新を取り込んだ方が良いと思います。
    ②input要素の選択。但し、ボタンとhidden型は除く。
    jQueryのセレクタを使って、対象とするinput要素の項目だけを選択します。
    また、今回は、<div></div>で囲まれた範囲(#Div要素のidを指定)のinput要素を対象としています。

    ③止まってはいけいない属性
    readonly属性、disabled属性のinput項目は、この条件で判断して除外します。

    ④onloadのタイミングでこの関数を実行
    画面要素が取り込まれたタイミングで、対象とするinput要素に適用させます。
    因みに、クロスブラウザ対応のコーディング例。

     

    3.input要素が動的に追加された時の対応
    入力の操作で、input要素(入力項目)が動的に追加されるケースがある場合、
    追加されたタイミングで、この関数を呼んでkeyPressイベント関数をリビルドします。
    そうすることで、追加したinput要素を適用対象と認識させます。

     

    今回はこれにて、以上。

  • 検索機能付きのセレクトボックス。jQueryのSelect2を使ってみる

    はじめに
    選択肢がたくさんあるセレクトボックスは、選ぶ時、縦に広がったボックスから見つけるのに苦労します。自前で絞り込みができる方法を考える前に、ネットで探してみたら、やっぱりありました。jQueryプラグインのSelect2です。このjQuery Select2は、ボックス内の検索、タグ付け、ajaxリクエストによるセレクト項目の設定等が出来て、Bootstrapテーマで簡単に実装できるセレクトボックスです。今回、JavaScriptのDOMを使って、セレクトボックスをHTMLページに動的に追加した際、つまづいた事があったので、そのメモ書きです。

    概要
    DOMでセレクトボックスを追加したら、その後、『$(‘select’).select2();』を実行しておくこと。 そうしないと、select要素がselect2で初期化されない。

    例)「好きな果物」セレクトボックス 追加ボタン付き

    select画像1
    select画像1

    1.ダウンロード
    ・seletc2
    https://select2.github.io/
    ・select2 bootstrapテーマ
    https://github.com/select2/select2-bootstrap-theme

    2.select2とbootstrapの準備
    jsとcssを取り込みます。

    <link href="(パス)/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
    <link href="(パス)/css/select2.min.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></></script>
    <script type="text/javascript" src="(パス)/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="(パス)/js/select2.min.js"></script>
    

    (パス)は適宜、環境に置き換えて下さい。jQueryはなるべく最新を取り込んだ方が良いと思います。

    3.DOMによるselect要素の追加操作

    コーディング例です。

    (1) html

    <table align=left>
     <tr>
      <td  style="width:100px;height:30px;text-align:center;background-color: #ffffff;border:1px solid #000000;" >
       <span>好きな果物</span>
      /td>
      <td style="width:200px;height:30px;text-align:center;background-color: #ffffff;border:1px solid #000000;" >
       <select class="select" name="cSelFruit_1" id="cSelFruit_1" >
        <option value="0" selected>  </option>
        <option value="1" >バナナ</option>
        <option value="2" >イチゴ</option>
        <option value="3" >メロン</option>
        <option value="4" >リンゴ</option>
        <option value="5" >グレープフルーツ</option>
       </select>
      </td>
      <td nowrap align=center><button type="button"  id="btnInsert_1" onClick="fOnClickInsert(this);"  >追加</button></td>
     </tr>
     <tr id="InsertLineEnd"></tr>
    </table>
    
    <!--追加行ひな型 ここから -->
    <table  style="visibility:hidden;" id="masterDefault">
     <tr id="II_prototype">
      <td  style="width:60px;height:30px;text-align:center;background-color: #ffffff;border:1px solid #000000;" >
       <span>好きな果物</span>
      </td>
      <td style="width:60px;height:30px;text-align:center;background-color: #ffffff;border:1px solid #000000;" >
        <select name="cSelFruit" id="cSelFruit" >
         <option value="0" selected>  </option>
         <option value="1" >バナナ</option>
         <option value="2" >イチゴ</option>
         <option value="3" >メロン</option>
         <option value="4" >リンゴ</option>
         <option value="5" >グレープフルーツ</option>
        </select>
      </td>
      <td nowrap align=center><button type="button"  id="btnInsert" onClick="fOnClickInsert(this);"  >追加</button></td>
     </tr>
    </table>
    <!-- ひな型 ここまで-->
    

    (2) javascript

    // ①静的に実装されているセレクトボックスの初期化
    $(function(){
     $('.select').select2();
    });
    
    // select要素の追加 
    function fOnClickInsert(oPara){
    // 操作した行番号を取得  oPara.id 例) "cSelFruit_1"
     var aWork = oPara.id.split("_");
     var nLineNo = aWork[aWork.length - 1];
    
    // ひな型行オブジェクトの取得
     var oLine1 = document.getElementById("II_prototype");
    
    // 追加する行オブジェクトを作成する
     var oNewLine1 = oLine1.cloneNode(true);
    
     var oNewLine_td = "";
     var oNewLine_select = "";
    
    // ここから属性情報設定
     var nNewLineNo = parseInt(nLineNo) + 1;
    
    // td,button,select情報の設定
     oNewLine_button = oNewLine1.getElementsByTagName("button");
     oNewLine_select = oNewLine1.getElementsByTagName("select");
    
    // ボタン
     for (i=0;i<oNewLine_button.length;i++){
      if(oNewLine_button.item(i).id == "btnInsert"){ // 追加ボタン
       oNewLine_button.item(i).id   = "btnInsert_" + nNewLineNo;
      }
      else {
       continue;
      }
     }
    // セレクトボックス
     for (i=0;i<oNewLine_select.length;i++){
      if(oNewLine_select.item(i).id == "cSelFruit"){	// 好きな果物
       oNewLine_select.item(i).id   = "cSelFruit_" + nNewLineNo;
       oNewLine_select.item(i).name = "cSelFruit_" + nNewLineNo;
    
       // ②classはここで設定しないと、効かない。
       oNewLine_select.item(i).className = "select"; 
      }
      else {
       continue;
      }
     }
     // 行追加
     oAfterLine = document.getElementById("InsertLineEnd");
     oAfterLine.parentNode.insertBefore(oNewLine1,oAfterLine);
     
     // ③ここで動的に追加したセレクトボックスの初期化
     $('.select').select2();	
    
     return;
    }

    ①のセレクトボックスの初期化は、ロードされた時点で実装されているselect要素に対して、適用されます。
    ②のクラス設定は、このタイミングで設定しないとうまく効きません。
    ③のタイミングで、直前に追加したselect要素がselect2に初期化されます。

    4.追加ボタンを押した結果

    select画像2
    select画像2