HTMLフォームでエンターキー押して入力要素のフォーカスを移動させたい、いや、しろよ!

HTMLでフォームをチマチマ組んでテストしていると、テキストボックス(input[type=text]要素)とかでついついエンターキー(改行キー)を押して、ムカッ!!!!!!とかしません? するよね、絶対するよね? 僕は自己嫌悪に陥って仕事を中断して帰りたくなる衝動に駆られます!

そこでググってjQueryのプラグイン探すなり、テック系の記事をコピペしたりしますよね。でも僕は探すより、自分で書く方が早いんですよ、結果的に。適当なjQueryプラグインなりを探してもそれの使い方を調べてたり、要らない機能があったりして、結局ドキュメントをよく読まないとわからないことが多い。

要は FORM要素内のINPUT要素に onkeyupイベントハンドラを仕込んでエンターキーをトラップすれば済む話。
たかだか数十行のスクリプトです。え?自分で組むとバグが!!!って? バグが出たらその都度直せばいいんです。ラクしちゃいけません。ラクするのはチラシの印刷だけでよろしい。

僕は jQuery 好き好き人間なので、適当にプラグインを書きました。

/********************************************************************
  filename: jquery.enterNext.js
  usage: call bellow...

   $('form').enterNext();

********************************************************************/
(function($,undefined)
 {
   $.enterNext =
     {
       config:
         {
           selectors: [
             'input[type="text"]',
             'input[type="password"]',
             'input[type="email"]',
             'input[type="number"]',
             'select',
             'textarea'
           ]
         }
     };

   var enterNextInternal = function(setting)
   {
     var selectors = setting.selectors.join(',');
     var $controls = $(selectors,this);
     var lastIndex = $controls.length - 1;
     var onKeyUp =  function(ev) 
     {
       if(this.tagName.match(/input/i) && ev.keyCode == 13)
       {
         var currentIndex = $controls.index(this);
         var nextIndex = currentIndex + 1;
         if(currentIndex == lastIndex)
           nextIndex = 0;

         var nextObject = $controls.get(nextIndex);
         nextObject.focus();
       }
     };
     $(this).on('keyup',selectors,onKeyUp);
   };
   
   $.fn.enterNext = function(options)
   {
     return this.each( function() { enterNextInternal.call(this,$.extend(true,{},$.enterNext.config,options)); });
   };
   
 })(jQuery);

で、これを以下のようなフォームで使うと、このままでは失敗して、エンターキー押すとフォームが送信されてしまいます。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <style type="text/css"><!--
      form input[type=text] {
        display: block;
        margin: 1em 0;
        padding: 5px;
      }
    --></style>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript" src="./jquery.enternext.js"></script>
  </head>
  <body>
    <div id="main">

      <!--メインコンテンツ-->
      <div id="contents">
        <div class="inner">
          <form method="post">
            <input type="text" name="a" value="" required />
            <input type="text" name="b" value="" />
            <input type="text" name="c" value="" />
            <input type="text" name="d" value="" />
            <input type="text" name="e" value="" />
            <input type="submit" value="送信">
          </form>
        </div>
      </div>

    </div><!-- #main -->
    <script type="text/javascript"><!--
      (function($) {
        $('form').enterNext();
      })(jQuery);

    //--></script>
  </body>
</html>

失敗の原因は、FORM要素内に input[type=submit]要素が存在するのが原因。
chromiumしか確認していないけど、どうやら input[type=submit]要素が存在すると、エンターキー押下で問答無用でFORMのアクションが走るようです。このinput[type=submit]要素を消すと送信されない、という挙動になってます。違ったらごめん。

じゃぁ、FORM要素にinput[type=button]要素なりa要素なりを書いて、そのonclickイベントハンドラ内で FORM要素のsubmitメソッドをコールすればいいんじゃない?ということになるんですが、残念ながらそうは問屋は降ろさない。
input[type=submit]要素がないと、FORM要素のvalidityチェックが走らないんだな、これが。せっかくinput要素に requireだのpatternだのを書いても無視されてしまう。

解決方法は2つ。

(1)
input[type=button]要素のonclickハンドラ内で、FORM要素のsubmitメソッドをコールする前に、reportValidityというメソッドをコールしてその返り値を判断して submitメソッドをコールするかどうかを決定する。

    <script type="text/javascript"><!--
      (function($) {
        $('form').enterNext();
        $('form [type=button]').click(function(ev) {
          if(this.form.reportValidity())
            this.form.submit();
        });

      })(jQuery);

    //--></script>

(2)
input[type=submit]要素を隠すか非表示(display: none;とか)にしておき、input[type=button]要素のonclickハンドラとFORM要素のonsubmitイベントハンドラを仕込んでおいてエンターキー押下かではなくクリックされたかをチェックさせる。

    <form>
    ....
    <input type="submit" style="display:none;" />
    <input type="button" value="送信" />
    </form>
    <script type="text/javascript"><!--
      (function($) {
        $('form').enterNext();

        $('form').submit(function(ev) {
          if(!isClick in this || this.isClick !== true)
          {
            ev.preventDefault();
            return false;
          }
        });
        $('form [type=button]').click(function(ev) {
          $('form').prop('isClick',true).find('[type=submit]').click();
        });

      })(jQuery);

    //--></script>

最初(2)の方を使ってたんだけど、(1)の方がカンタンなので、そっちにした。単に reportValidityというメソッドを後から知ったんだけどね💦

ちなみに、FORMのvalidityチェックの際、エラーメッセージをカスタマイズするプラグインもついで書いた。プラグインにするほどのものでもないけど、一回一回書くのはめんどっちーのでプラグインにした方がラク、というだけの理由ですけどね。

/******************************************************************
  Filename: jquery.validity.js
  入力必須の際のエラーメッセージをカスタマイズします。

   usage:
   <input type="text" pattern="^[0-9]*$" name="hogehoge" />

   $('input[type=text]').validity('半角数字で入力してください');
*******************************************************************/
;
(function($,undefined)
 {
   //デフォルト値
   $.validityMessage = 'この項目は入力必須です。';

   var validity = function(message)
   {
     if(message.length == 0)
       message = $.validityMessage;

     $(this)
       .on('invalid',function(ev) {
         if(this.validity.valueMissing || this.validity.patternMismatch || this.validity.typeMismatch)
         {
           this.setCustomValidity(message);
         }
         else
         {
           this.setCustomValidity('');
           ev.preventDefault();
         }
       })
      .on('input',function(ev) {
        this.setCustomValidity('');
      });
   };
   
   //plugin body
   $.fn.validity = function(message)
     {
       return this.each(function()
                        {
                          validity.call(this,message);
                        });
     };
   
 })(jQuery);

Windows10でこれだけ知ってれば飯食える(大嘘)基本キーボード操作

Linuxでターミナル中心にCUIでゴニョゴニョやってると、脳内がGUIからCUIになりつつあります。そりゃそうだよね、マウスでごちゃごちゃやるより、コマンド一発叩けば処理完了すんだから。

で、脳内がCUIに侵されつつある今、Windows10でもそれをやろう、というわけです。原点回帰です。MS-DOSは良かったな!的な。
Windows10ではすでにWSLがあるので、テキスト処理はもう快適です。コマンドプロンプトでの type とか findstr とかいう、意味わかんねーコマンドを叩く必要はありません。WSLで cat, grep できます。WSLで標準出力をクリップボードにも転送できるし、もちろん Windowsのコンソールプログラムにパイプで接続できますし、正直、昔のマイクロソフトはなんだったんだ?ってな具合です。

閑話休題。

本題です。脳内がCUIに侵されつつあるので、できるだけ Windowsでもマウスを触りたくないのです。特にエディタ(gVimとか)でガシガシコーディングしてると、キーボードから手を放したくないのです。

よく忘れるので、備忘録として残してます。

キーボードショットカット編
※ WIN は ウィンドウズキーでキーボードのWindowsのロゴがプリントされているキー。

( 1)WIN + SHIFT + S: スクショ
( 2)WIN + PAUSE: コントロールパネル⇒システム
( 3)WIN + . (ピリオド) :絵文字入力パレットを出す
( 4)WIN + , (カンマ) :押している間だけ 全ウィンドウを非表示(デスクトップ上のアイコン確認用途?)
( 5)WIN + +(プラス): 拡大鏡(拡大)
( 6)WIN + – (ハイフン):拡大鏡(縮小)
( 7)WIN + E :エクスプローラのE (エクスプローラ起動)
( 8)WIN + R :実行(Run) の R (コマンドを指定して実行ダイアログ)
( 9)WIN + D :デスクトップのD (全ウィンドウ表示・非表示の切り替え)
(10)WIN + I :INSTITUTE?の I (Windowsの設定を開く)
(11)WIN + G :GAMEのG (ゲーム用の情報FPSとか?を出す)
(12)WIN + V : なんのVだ? クリップボードの履歴表示

POWERSHELL編
※ コマンドの後に パイプで ogv に渡すとグリッドビューウィンドウで表示してくれる
 ( ogvは Out-GridView のエイリアス)

(1)gip LANインターフェイスのIPアドレス他の情報表示( Get-NetIPConfigurationのエイリアス)
   ipconfigコマンドよりこっちのほうがプロっぽいでしょワラ
(2)gin コンピュータの情報一覧 msinfo32のコンソール版?(Get-ComputerInfoのエイリアス)
(3)Get-NetAdapter (認識されているLANアダプター一覧)
(4)Get-NetFirewallRule (Windowsファイヤーウォール規則の一覧表示)

Powershellは.NET Fremeworkのほぼ100%にアクセスでき、NET Frameworkのクラスライブラリのほぼすべてのインスタンスを生成して使用することができる最強のシェルです。またレジストリを普通のファイル・ディレクトリのように扱えたりできて、マイクロソフトが提供するコマンドレット・ライブラリによってWindowsの設定、各種機能のインストールなど、Windowsのすべてを制御できるWindows=PowerShellといっても過言ではないでしょう。 水を飲むように、呼吸するように、Powershellを使えなければWindowsで飯を食うのは難しいでしょう。(そんなこたぁーねぇよ)

コマンドプロンプト編(POWERSHELL上でも可能)WSLなしでもOK
(1)where : unix系コマンドでいうところの which コマンドです。
(2)clip : 標準出力をパイプでつないでクリップボードにコピー。ex) dir | clip
(3)nbtstat -a コンピュータ名 :LAN内のNETBIOSコンピュータ名から情報を取得
(4)curl:ファイル送受信コマンド(最新のWindows10では標準で使えるようになってます)
(5)scp :リモートファイルコピーコマンド (最新のWindows10で OpenSSHがサポートされてます)

要望としてはnetcatも標準でサポートして欲しい。。。powershellではスクリプト組めばなんとかできそうだけどね。netcat相当のコマンドレットも提供して欲しいよ、標準で。

随時追加中。。。

LAMP環境からSQLServerインスタンスの接続ポート番号を取得する

制作中の業務用ウェブシステムがSQLServer縛りなので、ここ2~3年急にSQLServerをいじることが多くなってきています💦 別の大半の仕事は MySQLかSQLiteなのですが、やはり WindowsのデファクトスタンダードのDBMSはSQLServer、ツール類は断トツに整備されていじりやすい!

そんなことはともかく。いつも前置きが長いです。すみません。

通常SQLServerインスタンスへコンピューター名(or IPアドレス)\インスタンス名 で接続するので特に接続ポート番号(動的ポート)を意識せずとも接続できると思われます。

ただ、僕はLAMP環境メインでやってきているので、ASP.NETとかいうのは肌に合いませんし💦 今更関わろうとも思いません。(C#でのデスクトップアプリやツール類の作成は趣味でやっているのですが・・・)
Linux側からWindows Server+SQLServerにする場合、大抵の場合SQLServerインスタンスのポートを固定して、ファイヤーウォールでそのポート番号を開けて・・・というやり方が一番ラクですし、今開発中のものもそういう環境でやると思います。

で、ふと思ったのですが、動的ポートって「動的」って言うんだから変わることを前提にしないといけないなぁ・・・と漠然と思いまして、カンタンなSQLServerインスタンスの情報を取得する方法がないかと思いまして・・・このエントリはその時に調べた内容です。

Windowsクライアントメイン(大概がAccessランタイムアプリ)の職場環境だと、大抵の場合「名前付きインスタンス」で動的ポートになっていると思います。職場環境によってはポート固定への変更を頑なに拒まれることもあろうかと思いますし、結局のところ一体何番で接続していいのか困ることがあります。

とりあえず、ググるが、SQLServer Browserサービスに直接問合せることで、SQLServerインスタンスの情報を得られますよ~、的な、事しかわかりません。

マイクロソフトのドキュメントによると、SQLServer Browserへの問合せはSSRP(SQL Server Resolution Protocol)というプロトコルでアクセスするみたいです。
[MC-SQLR]: SQL Server Resolution Protocol

これを読むと、UDP/1434ポート(SQLServer Browserサービス)へ、下図のように、インスタンス名の前に0x04をつけて問い合わせると、セミコロン区切りで情報を投げてくれるそうです。

(上記URLのドキュメントより抜粋)

なんだ!カンタンじゃん!(ほんとかよ。。。)

もちろんですが、SQLServerホストのファイヤーウォールでUDP/1434ポートを開けておく必要がありますが、普通は空いているでしょう、さもないと外部クライアントから一切接続できなくなるし。

とりあえず、ターミナルからローカルで動いているSQLServer(Deverlopper edition)ホストへ netcat で叩いてみる。
インスタンス名は既定のインスタンス(MSSQLSERVER)。

$ echo -ne "\04mssqlserver" | nc -u localhost 1434
Y ServerName;XXXXXX;InstanceName;MSSQLSERVER;IsClustered;No;Version;14.0.1000.169;tcp;1433;;

一応ローカルで動かしているSQLServerは固定ポートで動かしているので 1433になってまつね。。。
これだけだとプロトコル・ポート番号とインスタンスのSQLServerのバージョンなどが取れます。IsClusteredは・・・なんなんでしょうね?無知ですみません。

結果のフォーマットは、先頭(0バイト名)に1バイトの識別記号?の\x05、1バイト目にペイロード長(終端ヌルを除く)を示す16ビット整数、3バイト目からペイロード・・・という風な感じ。ペイロードはセミコロン区切りで、名前1;値1;名前2;値2;….;; という風なフォーマット。これなら簡単に連想配列かなんかにパースできます。

んで、インスタンスの簡易情報を取得するコードを書いてみる。

<?php
/*************************************************************************************
SQLServer名前付きインスタンスの情報を得る。
File: query_sqlbrowser.php
*************************************************************************************/
function queryNamedInstance($host,$instanceName,$queryPort = 1434)
{
  static $timeout = 5;
  $fp = fsockopen('udp://'.$host,$queryPort,$errno,$errstr,$timeout);
  if($fp === false)
    throw new RuntimeException($errstr);

  $str = sprintf('%s%s%s',hex2bin('04'),$instanceName,hex2bin('00'));

  if(false === fwrite($fp,$str,strlen($str)))
    throw new RuntimeException(_('failed to fwrite to resouce pointer'));

  $rv = fread($fp,1500);
  fclose($fp);

  $head = substr($rv,0,1);
  list(,$len) = unpack('v',substr($rv,1,2));
  $data = explode(';',substr($rv,3,$len));
  $rv = array();
  $i = 0;
  while(array_key_exists($i,$data) && array_key_exists($i+1,$data))
  {
    if(!empty($data[$i]))
      $rv[$data[$i]] = $data[$i+1];

    $i+=2;
  }

  return $rv;
}

この関数を実行してみると

<?php
require 'query_sqlbrowser.php';
print_r(queryNamedInstance('IPアドレス','インスタンス名'));

/***** 出力 *****
Array
(
  [ServerName] => コンピュータ名
  [InstanceName] => インスタンス名
  [IsClustered] => No
  [Version] => 10.50.4000.0
  [tcp] => 49179
)
****************/

とりあえす、これで得られたポート番号をキャッシュしておき、接続試行がタイムアウトしたら、キャッシュ更新・・・という感じで組み込もうかと思います。

11.6インチのサブモニタ

机の脇において使っていた、メーカー不明のフルセグ対応のポータブルテレビ(10インチ)が壊れてしまい、同じ大きさのテレビを探してたんですが、パナソニックとかシャープにはポータブルテレビがあるにはあるんですが、いずれも無線で信号を送る形式ばかり。
壊れたやつはHDMI入力もできて重宝してたので、HDMI入力ができるものを探してはみたんですが、なんか怪しげな中華製品が多く、どれもレビューがいまいち。

地デジBlulayレコーダーはすでに持っているので、地デジチューナー内蔵は諦めて、今度はHDMI入力ができる小型モニタを探し始めた。
・・・が、10インチ前後となるともう数が限られ、これまた怪しげな中華製品ばかり。しかもレビューもイマイチ。。。

こういうニッチ製品は大手メーカーは儲からないので作って売ってくれない。

で、こういうニッチ製品を多数作ってくれているCenturyの小型モニタに頼る。ヨドバシで29,800円で買う。23インチ前後のフルHD液晶モニタが安いやつだと19,800円ぐらいでいっぱいあるので・・・まぁ、それと比べるとちょっと高い感じがしますが、まぁ一般的にこのサイズのモニタはほとんど売れないと思うので需要と供給のバランスからみてもしょうがないんでしょうねぇ。

Century LCD-11600FHD2
FULL HD。1920×1080のみドットバイドット表示。型番に2とあったので、初代とどこが違うんだろう・・

ノングレア・IPSパネルみたいで、映りは非常にキレイです。ただ同時発色数が少ないのか夕焼けとかのグラデーション表示時、バンディングが出ます。まぁ気になるところはそれぐらいで画質面でこれといって不満はありません。

レコーダーでHDMIをつないでテレビやビデオのモニタとしてみる分には、スピーカーも内蔵されているので問題なし。
ただ、1点、分かっていたことですが、音量の調節が・・・すんげぇやりにくい・・・。パソコンとつないでサブモニタとして使うぶんには音量調節は関係ありませんが・・・、レコーダーとつないで単体で使用すると、音量調節がしにくいのは致命的・・・。レコーダー側のリモコンで音量調節できる機種(そんなのあるのかな?)だと問題ないんだけどねぇ。。。まぁ、音量調節だけ全面のフレームにつけてほしいなぁ・・・まぁ、そんなことしたらコストが跳ね上がるのはわかるんですけどね。。。

画面が思っていた以上に美しい発色なので満足してます😆

テーブルヘッダの固定

これまで、tableタグ内で thead要素を固定してtbody要素をスクロール可能にするために、
table要素の外側の要素の高さを固定してposition:relative、overflow:autoと指定して、下記のような自作の簡易jQueryプラグインを使用していました。

実際のデモ

HTMLとCSS

<div class="table-container">
  <table>
    <thead>
      <tr>
        <th>カラム1</th>
        <th>カラム2</th>
        <th>カラム3</th>
        <th>カラム4</th>
        <th>カラム5</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>カラムデータ1</td>
        <td>カラムデータ2</td>
        <td>カラムデータ3</td>
        <td>カラムデータ4</td>
        <td>カラムデータ5</td>
      </tr>
       ...
       ...
    </tbody>
  </table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="./jquery.headerFixedTable.js"></script>
<script type="text/javascript"><!--
(function($) {
  $('.table-container').headFixed();
})(jQuery);
//--></script>

.table-container {
  position: relative;
  overflow: auto;
  height: 100px;
  width: 80%;
  border: 1px solid #ccc;
}
.table-container table {
  width: 100%;
  border-collapse: collapse;
}
.table-container table > thead {
  background-color: #eee;
}
.table-container table > thead th {
  border-bottom: 2px solid #ccc !important;
}
.table-container table > tbody {
  background-color: white;
}
.table-container table tr > * {
  text-align: left;
  border-bottom: 1px solid #ccc;
}
.table-container table > tbody > tr:last-child > * {
  border-bottom: none !important;
}

jQueryのプラグインは適当に作成。汎用性はなし。

/******************************************************************************
  thead固定テーブル
  require following... 
     <div class="table-wrap" style="position: relative;">
       <table>
         <thead>...</thead>
         <tbody>...</tbody>
       </table>
     </div>
     <script type="text/javascript">
        (function($) {
           $('.table-wrap').headFixed();
        })(jQuery);
     </script>

 要点としては、table要素を複製して、複製したテーブルはtheadだけを、元のテーブルはtbodyのみを表示するようにする。
 その際 displayプロパティにすると元table,複製tableの各々カラム幅が揃わなくなるので、
 display: none ではなく、visibility:hiddenを適用する。
******************************************************************************/
(function($) {
  $.fn.headFixed = function()
  {
    return this.each(function() {
      var $table = $(this).find('table:first');

      var $wrapElement = 
        $('<div>')
        .css({'position': 'absolute','top': 0,'left':0,'width': $table.outerWidth(),'overflow':'hidden'})
        .height($table.find('thead').outerHeight());

      var $wrap = 
        $table
          .clone()
          .insertAfter($table)
          .wrap($wrapElement)
          .css('width','100%')
          .find('tbody')
          .css({'visiblity': 'hidden'})
          .end()
          .parent();

      $table
        .find('thead')
        .css({'z-index':10,'visibility': 'hidden'});

      $(this).on('scroll',function() {
        $wrap.css({'top':$(this).scrollTop()});
      });

      // ウィンドウのリサイズに追随
      $(window).resize(function() {
        $wrap.width($table.outerWidth());
      });
    });
  };
})(jQuery);

で、最近 display: sticky というのがあって便利だよ、というのを今更ながら知りまして、chrome,firefox用の画面にはこれを使うようしました。
MDNサイトで見ると「粘着位置指定要素 (stickily positioned element)」と言うそうで、要はイケてるサイトでよく見る、
下方スクロールしたら勝手にメニューなんかがページ上部に張り付く(固定される)挙動を簡単に実現できる CSSプロパティみたいです。

stickily positioned elementとは、 position の計算値が sticky である要素です。これは包含ブロックがフロールート (又はその中でスクロールするコンテナー) 内の指定されたしきい値 (例えば top に設定された auto 以外の値など) を達するまでは相対的な配置として扱われ、包含ブロックの反対の端が来るまでその位置に「粘着」するものとして扱われます。

これ読んでも、正直よく分かりません💦 すみません。

で、これをテーブルヘッダに利用しよう、というわけです。
ググると結構記事になっていて、要するに thead要素内の th要素に display:sticky を指定して固定するようです。

実際のデモ

theadをstickyにするのが真っ当な感じですが、現在のブラウザのバージョンでは thead を固定することはできないみたい(無視される)。
それと、th要素をstickyで固定しても、th要素に適用されている border は固定されないみたいな挙動になる感じです(若干ずれてしまう?)

/* 実際のCSS */
.table-container {
  position: relative;
  overflow: auto;
  height: 100px;
  width: 80%;
  border: 1px solid #ccc;
}
.table-container table {
  width: 100%;
  border-collapse: collapse;
}
.table-container table > thead {
  background-color: #eee;
}
.table-container table > thead th {
  border-bottom: 2px solid #ccc !important;
  position: -webkit-sticky !important;
  position: sticky !important;
  z-index: 2 !important;
  top:0 !important;
}
.table-container table > tbody {
  background-color: white;
}
.table-container table tr > * {
  text-align: left;
  border-bottom: 1px solid #ccc;
}
.table-container table > tbody > tr:last-child > * {
  border-bottom: none !important;
}

HTMLはほとんど同じ 。最後のscript要素が要らないだけ。

<div class="table-container">
  <table>
    <thead>
      <tr>
        <th>カラム1</th>
        <th>カラム2</th>
        <th>カラム3</th>
        <th>カラム4</th>
        <th>カラム5</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>カラムデータ1</td>
        <td>カラムデータ2</td>
        <td>カラムデータ3</td>
        <td>カラムデータ4</td>
        <td>カラムデータ5</td>
      </tr>
       ...
       ...
    </tbody>
  </table>
</div>

ただし、Internet Explorerには全バージョンを通して非対応なので(display:stickyは単に無視される)、
かっこ悪いけどブラウザで判別し(navigator.userAgent)、IEの時のみjQueryプラグインを使用するように分岐するようにした。

たとえば、ウェブシステムで行をjavascriptで動的に増やしたり減らしたりするときは、行を追加したり削除したりする関数を一個作っておき、もしブラウザがIEなら 複製テーブル、複製元テーブル両方に行を追加したり、削除したり。なんにしてもメンドクサイが。
IEユーザーがいなくなれば、これも必要なくなるかなと。