投稿者: staff

  • 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

  • ACCESSのフォームでSQLServerのテーブルを更新したら『データの競合』エラーが発生

    1.事象
     ACCESSの単票フォームのレコードソースとしてSQLServerのテーブルを指定している。「Microsoft SQL Server Manager」を使い、このテーブルに次のような列を追加して、フォームで更新操作をしたらエラーが発生。

    追加した列: A項目  bit型  null可

    エラーメッセージ:データの競合

    “このレコードは他のユーザーによって変更されています。[レコードの保存]を選択すると、他のユーザーによる変更を無視し、自分が行った変更を反映します。[クリップボードにコピー]を選択すると、変更したデータはクリップボードコピーされ、他のユーザによる変更が反映されます。必要に応じて、クリップボードのデータを張り付け、自分が変更したデータに戻すこともできます。”

    なお、このエラーが出た時、もちろん操作をしているのは、自分だけです。

    2.対処と原因

    [対処]

     A項目 bit型 null可   →   A項目 bit型 null不可 (必須項目、初期値:0)

     nullを許容しない、必須項目とする事でエラーを回避しました。

    [原因]
     はっきりした原因は不明。ネットで検索した対処方法によると、どうやら、ACCESSでリンクする場合、bit型のようなBOOL属性の項目は、必須項目にしないとダメなようです。裏でどんな動きをして、今回のようなエラーが発生してしまうのか。

     以下、思った事。

     bit型は、ACCESSのデータ型ではYes/No型になります。ACCESSのフォームにおいて、チェックボックスの値を格納する時のデータ型として、よく利用します。なので、データはYESかNOかの2択で、nullはありません。今回、該当のテーブルは、元々、ACCESSのmdbのテーブルで、ACCESSのアップサイジング機能を利用してSQLServerのテーブルに変換したテーブルです。追加した列のプロパティは、そのテーブルにおいて既存のbit型列にならって設定しました。既存のbit型列は"null可"になっていました。同じように設定して、結果、エラーが起きました。改めて既存のbit型列のプロパティを見直したところ、拡張プロパティが設定されていたので、全て同じように設定しました。

    例えば、次の拡張プロパティ

    AllowZeroLength : False
    AppendOnly: False
    Attributes:1
    CollatingOrder:1041
    DataUpdatable:False
    MS_Format:Yes/No
    etc..(拡張プロパティは18項目あり)

     これらを設定しても、状況は変わりませんでした。さて、なんだろう。

     アップサイジング機能で変換されたbit型の列は、nullを許容する設定でしたが、既存レコードには値が全て設定されていました。後で、「Microsoft SQL Server Manager」で追加したbit型の列は、既存レコードにnull値が設定された状態になり、システム側で強制的に値を設定しようとして、結果的にその動作が競合となりエラーになってしまったのでしょうか。
    (根拠なし、想像です)

    以上

  • 『Googleニュース用RSSジェネレータ』で収集したニュースをPHPで編集・成形してWebサイトに表示する

      このブログで以前に紹介した“『Googleニュース用RSSジェネレータ』と『単眼RSS』を使って労働関連に関る最新ニュースのコンテンツを作る”の続編です。 ニュースの表示方法をもう少しカスタマイズしたくなったので、単眼RSSを使わないやり方で編集する方法を模索しました。以下を紹介します。
     
    [概要]
    ・googleニュースをPHPのSimpleXML拡張モジュールを使ってXMLオブジェクトに変換、さらにarray型データに変換する
    ・array型データの中から、Webサイトの表示に必要な項目を取り出して、htmlドキュメントを成形する

      
    1.googleニュースをPHPのSimpleXML拡張モジュールを使ってxmlオブジェクトに変換、さらにarray型データに変換する


     SimpleXML拡張モジュールは、php5.0.1以上から対応しているので、最近のレンタルサーバなら殆ど利用できると思います。まず、Googleニュース用RSSジェネレータ<http://g.1o4.jp/news-rss.html>でURIを生成します。そのURIで得たデータをSimpleXMLElement、SimpleXMLIteratorを使ってarray型に変換します。というような操作が、phpマニュアルサイトの「User Contributed Notes」のコーディング例 http://php.net/manual/ja/class.simplexmliterator.phpで紹介されていましたので、参考にしました。
      
    その例の中にあるxml2array()関数を使用した場合。

    [PHP コーディング例]  

    [crayon lang=”php”]
    // 例:uriは労働運動関連ニュースを10件取得する場合
    $uri = “https://news.google.com/news?ned=us&ie=UTF-8&oe=UTF-8&q=%E5%8A%B4%E5%83%8D%E3%80%80%E9%9B%87%E7%94%A8&output=atom&num=10&hl=ja”;
    // この関数は、コーディング例にあるユーザ関数です。詳細は、上記のphpマニュアルサイトのリンク先で確認してください。
    $rssAtomArray = xml2array($uri);
    [/crayon]

      
    2.array型データの中から、Webサイトの表示に必要な項目を取り出して、htmlドキュメントを成形する

    [php コーディング例]

    [crayon lang=”php”]
    $aWork = array(); // Webサイト表示に必要な項目のみ、取り出して保持しておく領域
    $aSortKey = array();// ソート用

    // Webサイトの表示に必要な情報だけを取り出す
    foreach ($rssAtomArray[“entry”] as $row){
    $jpDate = new DateTime($row[“updated”][0]);
    $jpDate->setTimezone(new DateTimeZone(“Asia/Tokyo”));
    array_push($aWork, array(“updated” => $jpDate->format(“Y/m/d H:i:s”), “title” => $row[“title”], “id”=> $row[“id”]));
    array_push($aSortKey, $jpDate->format(“Y/m/d H:i:s”));
    }
    array_multisort($aSortKey, SORT_DESC, $aWork); // ニュースは、更新日時の降順でソート。

    // html成形
    $cHTML = “

    “;
    foreach($aWork as $row) {
    $cHTML .= “

    “;
    $cHTML .= “

    “;
    $cHTML .= “

    “;
    }
    $cHTML .= “

    “.$row[“updated”].”
    “.$row[“title”][0].”

    “;
    echo $cHTML; // ブラウザに表示
    [/crayon]

    [説明]
    googleニュースで得たarrayデータの要素(=xmlのタグ)

    ・"updated" :ニュースの更新日時。atom(RFC3339) 形式の世界標準時だったので日本時間に変換
    ・"title" :ニュースのタイトル
    ・"id" :ニュースのリンク先情報

    これらの要素は、1.の処理の$rssAtomArrayをprint_r()で出力して、確認しました。
    今回は、googleニュースの場合ですが、他のxmlオブジェクトは、違ってくるかもしれません。
    後は、Webサイトに合わせて、htmlドキュメントを成形して、表示すればOKです。

    余談:
    XMLオブジェクトをArray型に変換する方法は、ネットで検索すると、json_decode、json_encodeを利用すると簡単にarray型に変換できる、と出てきます。試してみると、googleニュースで取得したデータは、階層が深いのか?うまく変換できませんでした。今回、紹介したSimpleXML拡張モジュールには、イテレータが用意されているので、それを使えばXMLオブジェクトのハンドリングは容易になりますね。
    (結局、phpマニュアルサイトのコーディング例を参考にしちゃうんですが)

  • BlenderでモデリングしたワイヤーフレームをFlashで描画再生してみる。

    はじめに

      今回の思いつきは、『Webサイトのコンテンツで、多面体のワイヤーフレーム画像を動かしたい。』です。幾つか実現方法はあると思うのですが、Blenderでモデリングを行い、そこで作られた頂点座標情報を取り込んでflashで再生する、という方法を選びました。
     
    1.Blenderでモデリング
       Blenderは、オープンソースの3次元CG開発ソフトウエア(統合開発環境)ですね。だいぶ前に同様のCGソフトのMetasequoiaで何かやろうとチャレンジした事があったのですが、挫折しました。そこでBlenderです。使い方は、次のサイトを参考にさせて頂きました。
    「Blender入門」(http://www.blender3d.biz/)大変感謝しています。

     以下、何とかリンゴをモデリング。

    blender
     

     

     

     


    2.頂点座標情報の取り込み
      モデリングしたリンゴの頂点座標情報の取り込みは、BlenderのExport機能で情報をファイル出力して、そのファイルから読み込む事にしました。幾つかあるファイルフォーマットの中から、Wavefront(.obj)フォーマットを選択。 このフォーマットで出力された3Dモデルデータが一番扱い易いと判断しました。 Wavefrontフォーマットの説明は、次のサイトを参考にさせて頂きました。
    「OBJファイルフォーマット」(http://www.hiramine.com/programming/3dmodelfileformat/objfileformat.html)
    大変感謝しています。
     OBJファイルフォーマットは、頂点座標値(x,y,z)データ、多面体の面(メッシュ)を構成する頂点座標を指すインデックス情報や、モデリングした時の法線ベクトルの情報等が含まれています。今回は、頂点座標値(x,y,z)データ、多面体の面(メッシュ)を構成する頂点座標を指すインデックス情報を利用します。
      
    3.flashで再生する
      objファイルを読み込んで描画するプログラムをAS3.0でコーディング。AS3.0を選んだのは、ブラウザ上で画像を操作できるインターフェース(各種イベントを拾える)が用意されている点がいいと思ったから。 AS3.0のコーディングは、次の本を参考にさせて頂きました。
    「C++による簡単実習 3次元CG入門」(http://www.morikita.co.jp/books/book/2149)
    言語はC++ですが、AS3.0でプログラミングする際に大変役に立ちました。
     [ワイヤーフレーム]

     wire

     
     

     

     

     

     

     

     

     

    [面を塗りつぶし  ]

    apple apple2

     

     

     

     

     

     

     

     

     

    今回はここまでです。

     

  • タスクイメージは破損しているか、または変更されています。(HRESULTからの例外:0x80041321)

    1.事象
     Windows7のパソコンにおいて、タスクスケジューラで毎日実行していたバックアップ処理が出来ていない事が発覚。とりあえず、実行記録を確認しようとタスクスケジューラを起動したらタイトルのエラーが発生。エラーメッセージの応答で[OK]をするが、引き続き同じメッセージが表示される。
    この操作は数十回繰り返した。おそらく、設定されていた多くのタスクに対してメッセージが表示されたと考えられる。バックアップ処理が出来ていなかったのは、このタスク設定が壊れてたためと断定。

    2.原因調査と対処
     とりあえず、タスクスケジューラの設定を元通りにする対処方法をネットで検索。同様の事象は過去にも結構出ているらしい。以下のサイトを参考に対処してみる。

      タスクスケジューラを開くとエラーメッセージが表示される「タスクスケジューラサービスが利用できません」
      http://answers.microsoft.com/ja-jp/windows/forum/windows_7-performance/%E3%82%BF%E3%82%B9%E3%82%AF%E3%82%B9%E3%82%B1/fde068e5-d1d5-4821-9888-b2270a428e6f?auth=1


     [対処: ”タスクのインポート”操作でタスクの再設定]
     C:\Windows\System32\Tasksフォルダ配下の全ファイルを任意の場所に移動してタスクスケジューラを起動。エラーは出なくなった。ここから、全部のタスクをインポートで再設定することにした。TasksフォルダにはWindowsやパソコンベンダー等のフォルダ配下に100を超える設定ファイルがある。気が滅入りながらちびちびやっていると、設定ファイルのタイムスタンプで気づきが・・。どうやらバックアップ処理が失敗した日の直近で更新されている設定ファイルが破損しているらしい。まず、設定ファイルのタイムスタンプをみてインポートしないで元に戻せるか判断。これでだいぶ楽になった。

     [タスクイメージが破損した原因(多分): Windows10->Windows7のダウングレード]

     しかし、以下のエラーが発生してインポート操作で復旧が出来ないタスクが出てきた。


     “タスクの形式が有効ではありません。(2,8):version:1.5”
     

     ネットを検索。以下が参考になりました。

      タスクスケジューラーで「タスクの形式が有効ではありません」と表示され作成できない
      http://answers.microsoft.com/ja-jp/windows/forum/windows_7-update/%E3%82%BF%E3%82%B9%E3%82%AF%E3%82%B9%E3%82%B1/b20e1938-22ee-4fce-8f71-db4fa66dcf50?auth=1

     確かに、破損している設定ファイルのタイムスタンプは、Windows10からWindows7に戻したタイミングと一致している!
     おそらく、元に戻す課程で破損してしまったのではなかろうか。但し、 原因が分かったところで、戻せないタスクがあるってことは問題だな。そのタスクが何をやっていたのかも分からないし。
     
      Microsoftめー、またやってくれたなー。

     おそらくWindows10にしてから元のOSに戻したパソコンは、こうなっている可能性が大。 一度、タスクスケジューラを起動して確認してみることをお勧めします。

     

  • jQueryのAjaxリクエスト(POST)で日本語の送信データが文字化け

    ブラウザ側入力フォームで指定した日本語文字列をAjaxリクエスト(POST)でサーバに渡した際、サーバ側で参照したら文字化けを起こしていてハマりました。

    jQuey日本語リファレンスをみると、サーバに送信するデータはクエリー文字列に変換されてGETリクエストとして付加されるとあったので、URLエンコードは自動的にやってくれると思いましたが、POSTの場合はこちらで変換した値を指定してあげないとダメなようです。
    以下、サンプル。日本語が入力されている「cSearchKeyWord」をencodeURIで変換してdata:{・・・・}に指定してます。

     var cSearchKeyWord = encodeURI(document.form001.cSearchKeyWord.value.trim());
     $.ajax({
      type:"POST",
      url:"送信URL",
      dataType:"html",
      data:{
       "cSearchKeyWord":cSearchKeyWord,
       "cHashTags":cHashTags,
       "cFromID":cFromID,
       "cToID":cToID,
       "nRetweetFlag":nRetweetFlag,
       "cGetCount":cGetCount
      }
     }).then(
      // 通信成功
      function(data,status,xhr){
      ・・・・
      },
      // 通信失敗
      function(xhr,status,error){
      ・・・・
      }
     );
     
    この結果にたどり着くまで、えらい時間が掛ってしまいました。phpのmb_stringとかhtmlの文字コード設定やら、php.iniの文字コードに関わる設定とかを改めて見直しました。結局、中途半端な知識で仕事をしてきているからハマると一から調べなおす事になってしまう。ネットで検索できて便利なのだけど、頭にちゃんと入らないんですよね。いかんなぁ・・・・。

  • SQLSERVERのViewをACCESSのMDBでODBC接続したが、ACCESSで表示する値が違う。

    (mdbでリンクする際、[固有レコード識別子の選択]は正確に行いましょう)


    ■事象
    ACCESSのMDBで、SQLSERVERで定義しているViewをODBC接続でリンクした。
    ACCESSで表示したところ、SQLSERVERのVIEWの表示が一部の列で値が違って表示されている。

    例)

    以下のようなView_TEST をMDBでリンクしたところ、表示した"単価"、"個数"列がSQLSERVERのViewと違って表示されている。

    View_TEST:

    select 店舗,販売日,品物,単価,count(*) as 個数 from TEST group by 店舗,販売日,品物,単価 order by A.

    [SQLSERVERの表示]

    店舗 販売日 品物 単価 個数
    支店A 2015/8/31 みかん 250 3
    支店A 2015/8/31 バナナ 100 25
    支店A 2015/8/31 バナナ 198 13

    [ACCESS MDBの表示]

    店舗 販売日 品物 単価 個数
    支店A 2015/8/31 みかん 250 3
    支店A 2015/8/31 バナナ 100 25
    支店A 2015/8/31 バナナ 100 25

      ※ 3行目の単価、個数が198、13のはずが、2行目の値になっている。

    ■原因と対応
    mdbでリンク指定する時に、[固有レコード識別子の選択]という操作があり、そのテーブルの主キーとなる項目を設定するのですが、この項目の選択が誤っていました。今回の場合、group byで集計していたら集計した列を全て指定しないと一意になりません。結果、おかしな表示になってます。(なぜ上記のような表示になるのかは疑問が残るが、そこは追及する意味がないと判断。)

    以前から、[固有レコード識別子の選択]は結構いい加減に考えていて、適当に設定していても問題なかったのですが、今回の不具合で改めて重要であることを認識しました。というか、ちゃんと理解して設定しろよ!正しく理解する為の時間を惜しんで、結局遠回りして痛い目に遭う。
    (こんな事、結構繰り返してます……OTL)
     

     

  • Access2013にはSQLServerへのアップサイジング機能が無いのです

    Access2010まで提供されていたSQL Serverへのアップサイジング機能
    (アップサイジングウィザード)が、Access2013では削除されてしまいました。

     ※Office 2013 での変更点
      https://technet.microsoft.com/ja-jp/library/cc178954.aspx

    処理速度改善の案件で、システムはLAN環境でAccessデータベース(mdb)をサーバに配置して
    クライアントPCのGUI画面から読み書きをしていたのだけど、Jet Database Engineの処理の
    仕方でどうしても処理速度が上がらないため、SQL Serverに移行してしまおう
    (無償のExpress Editionバージョン)となりました。

     そこで出番となったAccessの素晴らしい機能であるアップサイジングウィザードです。
    これを使えば、テーブルとそのデータだけでなく、インデックス、入力規則、テーブルの
    リレーション等も一緒にSQLServerのデータベースに移行してくれます。
    大変便利です。ところが。。。。表題のとおり。仕方がないのでAccess2010がインストール
    されている別のマシンで処理しました。

     移行の代替案としてSQLServerのインポート機能を利用しようと思いましたが、
    これだどテーブルとそのデータだけなんですよね。

    なぜ、MicrosoftはAccess2013で削除してしまったのか理由は分かりません。
    今後のAccessバージョンで復活してくれることを願いつつ、Access2010は無くさずに
    に大切に扱う使うこととします。

  • 『Googleニュース用RSSジェネレータ』と『単眼RSS』を使って労働運動に関る最新ニュースのコンテンツを作る

     今回は自分が興味のあるニュースを拾って、Webサイトに時系列で一覧表示する方法の紹介です。

     特定のニュースを収集する方法は、例えばニュースを配信するサイトが提供するRSSフィード情報をRSS対応ブラウザの「RSSリーダー」とか、「フィード」と呼ばれる機能を使って自動収集しておく、なんてやり方がありますね。でもこの方法だと、ブラウザのRSSリーダーで読む事しかできないので、何とかWebサイトに表示してニュースタイトルをクリックするとリンク先に飛べるようにしたいと思います。。。まずは、

    1.『Googleニュース用RSSジェネレータ』で、気になるキーワードが含まれるニュースのRSSフィードを生成する
      例えば、[雇用]というキーワードでRSSフィードを生成します。パラメータを選択して最後に「RSS生成」ボタンを押します。

     [Googleニュース用RSSジェネレータ  例)]

    ブログ画像4

     

     

     

     

     

     

     

     

     

    次に、

    2.ブログパーツ『単眼RSS』で、1で生成したRSSフィードによって自動取得した「ニュースタイトル」をリスト化するブログパーツを作成する
      『単眼RSS』のサイトで、いろいろパラメータ(簡単なもの)を設定します。1で生成したRSSフィードURLを入力します。最後に「貼付けコード生成」ボタンを押します。
      今回は、[雇用][労働]の2つのキーワードでニュースを選別してリスト化できるようにしました。

      [RSSフィード登録画面 例]

    ブログ画像5

     

     

     

     

     

     

     

     

     

    そして、

    3.2で生成したブログパーツをWebサイトにはめ込んでみる
      こんな感じになります。 如何でしょうか。こんな風にニュースが選別されて表示されていると、世の中の動きも把握しやすくなるのではないでしょうか。

    労働運動関連ニュース

     

    (2017/1/31) 「単眼RSS」を利用するとad広告が出てしまうため、削除しました。代替案は、2017/1/31の投稿“「Googleニュース用RSSジェネレータ」で収集したニュースをPHPで編集・成形してWebサイトに表示する”を参照してください。