C# DataGridViewRowをDataRowに変換する方法

DataGridViewのDataSourceにDataTableをセットしているとき、DataGridViewRowをDataRowに変換する方法。

_dataGridView というDataGridViewがあるとして、

DataGridViewRow _dgvr = _dataGridView.Rows[0];
DataRowView _drv = (DataRowView)_dgvr.DataBoundItem;
DataRow _dr = (DataRow)_drv.Row;

とすれば変換できます。

 

1+

C# DataTableに任意のColumnがあるか調べる

C# のDataTableで特定のカラムがあるか、有無を調べるには、Columns.Containsを使います。

DataTable _dt = new DataTable();
DataColumn _dc_name = new DataColumn("name");
DataColumn _dc_age = new DataColumn("age");
_dt.Columns.AddRange(new DataColumn[] { _dc_name, _dc_age });

if (_dt.Columns.Contains("age"))
{
    //処理
}

簡単ですな。

 

0

CSS 途中で要素を画面いっぱいに広げる

ヘッダーや、フッターを画面いっぱいに広げる場合、widthを100%に指定すればいいだけですが。

1607010001

mainの途中で背景だけ目一杯に広る場合、mainを2つに分けて、間に目一杯の枠を作る。なんてことをしてた時期がありまして。こんな感じで。

1607010003

非常に効率が悪かったわけですが、できればこんなふうにmainの途中でも画面いっぱいに広がる枠を入れられたら楽ですよね。こんな感じで。

1607010002

で、どうするかというと、意外と簡単で、広げたい部分をdiv要素で囲って、
幅方向のmarginにマイナスの値を設定して、マイナス分を、paddingで補います。

margin:0 -200%;
padding:0 200%;

とすれば、いいわけですが、それだけだと、はみ出た部分まで表示しようとスクロールバーが出てきてしまいます。なので、bodyに

overflow-x: hidden;

を適用すればいいのですが、なぜかiPhoneなどで画面を横向けにすると、bodyに適用したはずのoverflow-x: hidden の効果がでません。なので、bodyのすぐ内側に全体を囲むdiv要素を追加して、その要素にoverflow-x: hidden を適用します。

ポイントは、marginの幅に-200%、paddingの幅に200%を指定していて、このおかげで横幅いっぱいに広がります。
このままだと、内容物が外に出て行ってしまうので、text-alignでセンタリングします。
あと、bodyにoverflow-x: hidden;を指定してますが、こうしないとスクロールバーが出てきてしまうからです。

ここだけ目一杯広げる

参考になりました。http://css-eblog.com/csstechnique/overflow-menu.html

0

Office2013 英語版を日本語表記にしたい

裏ワザ的に、評価版のOffice2013日本語版や、Office2013日本語版のDVDがあれば、英語版をアンインストールしてから、日本語版をインストールしなおして、ライセンスキーは英語版のものを入れる。という手もあるようです。

ですが、結論からいうと、インストール済みのOffice2013英語版を日本語表記にするには、言語パックを購入して適用するしか手はありません。

https://www.microsoftstore.com/store/msjp/ja_JP/pdp/productID.266844700?lang=japanese

ちなみに、
https://technet.microsoft.com/ja-jp/library/cc179115.aspx#BKMK_LanguageInterfacePacks
をみると、LIP (Language Interface Pack)なら無料っと書いてあるけれど、LIPに日本語は含まれていません。なので、実質インストール済みのOffice2013英語版を日本語表記にするには、言語パックを購入するしか手はありません。

で、依頼のあったパソコンのOffice2013に言語パックを手に入れてインストーラを起動しようとしたのですが、なぜかインストール中の表示は出てこず、何事もなかったようになります。おかしいな、となんどか繰り返したのですが、ふとみるとOffice2013は日本語化されていました。

Office2010は言語パックの配布を終了しているようです。

 

0

Windowsでキーボードの配列がおかしくなった時の修正方法

Windwos7 Professionalを、英語版のWindwos7 Enterpriseにアップデートしたようで、その際にキーボードの配列がおかしくなったので見て欲しいと依頼がありました。

で、見てみると、一部のキーボードのキーに書いてある文字と、押して表示される文字が違うという現象が起きていました。特に記号関係のキーはめちゃくちゃ。

これは、使用しているキーボードが106配列(日本語)なのに、101配列(英語)として設定されているためです。
というわけで、解決策。

答えはマイクロソフトのオフィシャルページにあります。

https://support.microsoft.com/ja-jp/kb/927824

で、今回はレジストリを編集して対応できました。
以下、その方法ですが、レジストリは下手にいじると、致命的な問題が発生して、Windwosが起動しなくなってしまう場合もあります。とはいえ、必要な項目だけを間違えずに修正すればよく、それほど難しいものではないので、必要以上にビビる必要はないかと。

レジストリエディタを開く

まずは、レジストリエディタを開きます。

コマンドプロンプトで、regedit と入力します。
コマンドプロンプトは、Windows7なら、スタート→すべてのプログラム→アクセサリ に大抵入っています。
Windows8なら、すべてのアプリで、Windowsシステム ツールにあります。

regedit

レジストリ値を修正する

レジストリエディタが開いたら、HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters
を開きます。

HKEY_LOCAL_MACHINE をクリックすればツリーが開くので、SYSTEMをクリック。そしたら、今度はCurrentControlSetをクリック。という感じで順に開いていきます。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

i8042prtを開くと、Parametersがあって、そこをクリックすると目的のレジストリが表示されます。(この画面はWindwos8の場合です。ちなみに、LayerDriver KORというのは、韓国語用のレジストリキーなので、関係ありません。(削除した方がいい場合もあるようです)

i8042prt\Parameters

修正が必要なのは

LayerDriver JPN
OverrideKeyboardIdentifier
OverrideKeyboardSubtype
OverrideKeyboardType

の、4箇所。
一つづつ、修正します。
修正するレジストリの名前のうえで、マウスの右ボタンをクリックし、修正(M)をクリックします。
レジストリ値の修正
LayerDriver JPN がおそらく、kbd101.dllになっているので、kbd106.dll に修正。
1606240013

OverrideKeyboardIdentifier はPCAT_101KEYになっているので、PCAT_106KEYに修正。
1606240014

OverrideKeyboardSubtype は、2、に修正します。
1606240015 

OverrideKeyboardType は7ですが、おそらく修正はいらないと思います。
1606240008

修正が終わったら、ファイル(F)→レジストリエディタの終了(X)をクリック。
1606240009

Windwosの再起動

あとはWindowsを再起動し、キーボードが正しく操作できるか確認してみてください。

 

 

0

ブルートフォースアタック(総当り攻撃)を狙われた痕跡

 

ブルートフォースアタック(総当り攻撃)を狙われた痕跡がログに残っていました。

37.252.2.101 - - [22/Jun/2016:06:31:30 +0900] "GET /wp-login.php HTTP/1.1" 403 214 "http://accelboon.com/wp-login.php" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"
37.252.2.101 - - [22/Jun/2016:06:31:32 +0900] "GET /blog//wp-login.php HTTP/1.1" 404 216 "http://accelboon.com/blog//wp-login.php" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"
37.252.2.101 - - [22/Jun/2016:06:31:34 +0900] "GET /administrator/ HTTP/1.1" 404 212 "http://accelboon.com/administrator/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"
37.252.2.101 - - [22/Jun/2016:06:31:34 +0900] "GET /blog//administrator/ HTTP/1.1" 404 218 "http://accelboon.com/blog//administrator/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"
37.252.2.101 - - [22/Jun/2016:06:31:35 +0900] "GET /admin.php HTTP/1.1" 404 207 "http://accelboon.com/admin.php" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"
37.252.2.101 - - [22/Jun/2016:06:31:35 +0900] "GET /blog//admin.php HTTP/1.1" 404 213 "http://accelboon.com/blog//admin.php" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"
37.252.2.101 - - [22/Jun/2016:06:31:36 +0900] "GET /bitrix/admin/ HTTP/1.1" 404 211 "http://accelboon.com/bitrix/admin/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"
37.252.2.101 - - [22/Jun/2016:06:31:36 +0900] "GET /blog//bitrix/admin/ HTTP/1.1" 404 217 "http://accelboon.com/blog//bitrix/admin/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"
37.252.2.101 - - [22/Jun/2016:06:31:37 +0900] "GET /?q=user HTTP/1.1" 200 11413 "http://accelboon.com/?q=user" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"
37.252.2.101 - - [22/Jun/2016:06:31:39 +0900] "GET /blog//?q=user HTTP/1.1" 404 204 "http://accelboon.com/blog//?q=user" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"
37.252.2.101 - - [22/Jun/2016:06:31:40 +0900] "GET /index.php/admin/ HTTP/1.1" 301 - "http://accelboon.com/index.php/admin/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"
37.252.2.101 - - [22/Jun/2016:06:31:41 +0900] "GET /admin/ HTTP/1.1" 404 204 "http://accelboon.com/admin/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"
37.252.2.101 - - [22/Jun/2016:06:31:53 +0900] "GET /admin/ HTTP/1.1" 404 204 "http://accelboon.com/admin/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"

/wp-login.php
/blog//wp-login.php
/administrator/
/blog//administrator/
/admin.php
/blog//admin.php
/bitrix/admin/
/blog//bitrix/admin/
/?q=user
/blog//?q=user
/index.php/admin/
/admin/
/admin/

という感じで、プログラム的に入り口を探られた痕跡があります。

残念ながら(?)Wordpress本体はサブフォルダにインストールしているので、wp-adminは見つからなかったみたいですね。
でも、人間の目で見れば見つかっちゃうんですけどね。

というわけで、もしログイン画面がみつかって、ブルートフォースアタック(総当り攻撃)されないために対策。

WordPressのログイン画面に文字認証CAPTCHA)を追加する

まず、SI CAPTCHA Anti-Spamプラグイン をインストールします。
SI CAPTCHA Anti-Spam はAnti-Spamが示す通り、コメントスパム対策のためのプラグインなのですが、ログイン画面にも文字認証(CAPTCHA)を追加できます。

プラグインをインストールしただけでは、ログイン画面には文字承認は表示されません。
プラグインをインストール後に設定が必要です。

SI CAPTCHA Anti-Spamの設定

SI CAPTCHA Anti-Spamプラグインをインストールしたら、プラグインのところに、SI Captchaオプション 項目が追加されますので、そこをクリック。

SI Captcha Option

□ログインフォームでキャプチャを有効にする。 にチェックをつけて、[オプション更新] ボタンをクリックします。

ログインフォームでキャプチャを有効にする。

これでログイン画面に文字認証(CAPTCHA)が追加されます。

文字認証(CAPTCHA)
0

Advanced Custom Fieldsで選択肢が複数のフィールドをWP_Queryで取り出す

Advanced Custom Fields を使って、カスタムフィールドを活用することが多いのですが、フィールドタイプに「関連」を使うと、ある投稿に関連する、別の投稿を登録することができます。

Advanced Custom Fields のフィールドタイプ

で、その値は、get_field()で取り出すことができます。

$page_id = 16534;
$relation_page_id_list = get_field($page_id , 'relation')
print_r(relation_page_id_list);

戻り値は、配列なので、
Array ( [0] => 12130 )
となります。

WP_Queryで関連元を取り出す

これはこれでOKなのですが、今度は逆に、関連とされた投稿から、関連元を取り出す必要がある場合。

WP_Queryでmeta_keyとmeta_valueに値を入れて取り出すことになるのですが、

$shop_id = 12130;
$args = array (
	'posts_per_page' => 5,
	'post_type' => 'post',
	'post_status' => 'publish',
	'meta_key' => 'relation',
	'meta_value' => $shop_id,
);
$query = new WP_Query($args);

これでは取り出せません。
そもそも、get_field()で取り出した値が配列な時点で、無理だろうなー、と思うのですが案の定ですね。

では、そもそも、「関連」フィールドで保存されたmeta_valueはどんな形なのかというと、

$page_id = 16534;
$table = $wpdb->prefix . "postmeta";
$shops_id = $wpdb->get_results( "SELECT post_id , meta_value FROM $table WHERE meta_key = 'shopspage' AND post_id = " . $page_id , ARRAY_A);
print_r ($shops_id);

と直接SELECTをたたいてみるとこんな感じで、meta_valueには、シリアライズされたデータで保存されてることがわかります。

Array ( [0] => Array ( [post_id] => 16534 [meta_value] => a:1:{i:0;s:5:"12130";} ) )

なので、普通に、meta_valueで検索しても引っかかりません。
ではどうすればいいかというと、meta_valueそのものは文字列なので、LIKEで見つければいいのではと。

$shop_id = 12130;
$args = array (
	'posts_per_page' => 1,
	'post_type' => 'post',
	'post_status' => 'publish',
	'meta_key' => 'relation',
	'meta_value' => '"' . $shop_id . '"',
	'meta_compare' => 'LIKE',
);
$query = new WP_Query($args);

これで関連元のページ一覧を取得できます。

ちなみに、

'"' . $shop_id . '"'

と、わざわざダブルクォーテーションで囲っているのは、たとえば12130 は 121、1213、2130なんかでも引っかかってしまうからです。

0

WprdPress ウィジェットのタイトルを非表示にする

ウィジェットのタイトルを入力すると、フロント側のページで、たとえばサイドバーに入力したタイトルが表示されます。

でも、バナーのように、そもそも画像のなかにタイトルと同じ文字列が入っている場合など、タイトルを表示してほしくないときがあります。

そんな時は、ウィジェットのタイトル欄を未入力にしておけばOKなのですが、それはそれで今度は管理画面側でウィジェットのタイトルが表示されずに、どれがどれだかわかりにくくなって困ってしまいます。

widget_title フックで解決

そんなときには、以下のコードを functions.php に貼り付けます。

add_filter( 'widget_title', 'no_widget_title' );
function no_widget_title( $title ) {
	return null;
}

widget_title フックで、ウィジェットタイトルを出さないようにしてしまいます。

プラグインRemove Widget Titlesで解決

でも、これだとすべてのウィジェットタイトルを消してしまうことになります。
任意のウィジェットだけ消したいときにはどうするか。という、そんな時に便利なプラグインがこちら。

Remove Widget Titles

タイトルの先頭に ! を付けるだけで非表示にしてくれます。

ちなみに、Remove Widget Titles の内容はとてもシンプル(実質7行程度のスクリプト)なので、プラグインを増やしたくなければ、Remove Widget Titles の内容をfunctions.php に直接貼り付けてもOKです。

0

[JQuery] スクロールでTableのヘッダをシンプルに固定する(レスポンシブ対応)

行数の多いテーブルだと、スクロールしていくとヘッダ部分が消えてしまうので、固定したいときがあります。sそんなとき、なるべくシンプルにコーディングするには、固定用のテーブルを別に用意したほうがシンプルに済みます。

こんな感じで。

名前 性別 年齢
ハナ メス 5
モモ メス 6
コタロウ オス 8
ナナ メス 4
チョコ オス 5
モカ オス 6
リン メス 3
ココ メス 7
モコ オス 2
ラン メス 11
マロン オス 5
レオ オス 6
クルミ メス 8
コロ オス 9
ソラ オス 4
アズキ メス 5
アンズ メス 10
ココア オス 9
サクラ メス 7
メイ メス 9
タロウ オス 12
テン オス 16
ヒメ メス 4
フク メス 8
ルーク オス 6
ルナ メス 7
レオン オス 4
クッキー メス 13
クロ オス 5
チロル メス 6

 

はじめは、theadをposition:fixed;で固定しようかと試行錯誤したのですが、tableのborder幅に振り回されたり、レスポンシブで幅が変わるとうまく合わせられないとか、悪戦苦闘するうちに、固定用のtableを別途用意したほうがシンプルで簡単だという結論に至りました。

あらかじめ、列幅を決めておかないといけませんが、レスポンシブにも対応できます。

HTMLはこんな感じで。sheet がテーブル本体で、fixheader が固定用。

<table class="fixheader" style="display: none; position: fixed; top: 0;">
<thead>
<tr><th width="40%">名前</th><th width="30%">性別</th><th width="30%">年齢</th></tr>
</thead>
</table>

<table class="sheet">
<thead>
<tr><th width="40%">名前</th><th width="30%">性別</th><th width="30%">年齢</th></tr>
</thead>
<tbody>
<tr><td>ハナ</td><td>メス</td><td>5</td></tr>
<tr><td>モモ</td><td>メス</td><td>6</td></tr>
<tr><td>コタロウ</td><td>オス</td><td>8</td></tr>
<tr><td>ナナ</td><td>メス</td><td>4</td></tr>
<tr><td>チョコ</td><td>オス</td><td>5</td></tr>
<tr><td>モカ</td><td>オス</td><td>6</td></tr>
<tr><td>リン</td><td>メス</td><td>3</td></tr>
<tr><td>ココ</td><td>メス</td><td>7</td></tr>
<tr><td>モコ</td><td>オス</td><td>2</td></tr>
<tr><td>ラン</td><td>メス</td><td>11</td></tr>
<tr><td>マロン</td><td>オス</td><td>5</td></tr>
<tr><td>レオ</td><td>オス</td><td>6</td></tr>
<tr><td>クルミ</td><td>メス</td><td>8</td></tr>
<tr><td>コロ</td><td>オス</td><td>9</td></tr>
<tr><td>ソラ</td><td>オス</td><td>4</td></tr>
<tr><td>アズキ</td><td>メス</td><td>5</td></tr>
<tr><td>アンズ</td><td>メス</td><td>10</td></tr>
<tr><td>ココア</td><td>オス</td><td>9</td></tr>
<tr><td>サクラ</td><td>メス</td><td>7</td></tr>
<tr><td>メイ</td><td>メス</td><td>9</td></tr>
<tr><td>タロウ</td><td>オス</td><td>12</td></tr>
<tr><td>テン</td><td>オス</td><td>16</td></tr>
<tr><td>ヒメ</td><td>メス</td><td>4</td></tr>
<tr><td>フク</td><td>メス</td><td>8</td></tr>
<tr><td>ルーク</td><td>オス</td><td>6</td></tr>
<tr><td>ルナ</td><td>メス</td><td>7</td></tr>
<tr><td>レオン</td><td>オス</td><td>4</td></tr>
<tr><td>クッキー</td><td>メス</td><td>13</td></tr>
<tr><td>クロ</td><td>オス</td><td>5</td></tr>
<tr><td>チロル</td><td>メス</td><td>6</td></tr>
</tbody>
</table>

 

JQueryは、スクロールでテーブルが一番上に来たら、固定用テーブル(fixheader)を表示させるだけの簡単なものです。

ただし、レスポンシブで幅が変わったときのために、$(window).resize でテーブル幅を一致させています。

<script>
            jQuery(function($){
                var tableSheet = $('table.sheet');
                var offset = tableSheet.offset();
                $('.fixheader').width(tableSheet.width());

                $(window).scroll(function () {
                    if($(window).scrollTop() > tableSheet.offset().top
                    && $(window).scrollTop() < (tableSheet.offset().top + tableSheet.height() ) ) {
                        var fixheaderTop = $(window).scrollTop();
                        $('.fixheader').show();
                    } else {
                        $('.fixheader').hide();
                    }
                });
                
                $(window).resize(function() {
                    $('.fixheader').width(tableSheet.width());
                });

            });
</script>
1+

Breadcrumb NavXT でカスタムタクソノミーのリンクを追加する

Breadcrumb NavXT で表示されるタームを追加して、カスタムタクソノミーのアーカイブページへのリンクを追加します。

たとえば、投稿にカテゴリーとは別に「plugins」というカスタムタクソノミーがあるとします。

pluginsが設定されている投稿ページが表示されたときには、パン屑リストに、pluginsのアーカイブページへのリンクを表示する、というようにしたい場合、次のようにします。

add_action('bcn_after_fill', 'my_filter_breadcrumbs_after');
function my_filter_breadcrumbs_after($bcnObj) {
	if ( count($bcnObj->trail) > 0 ) {
		if (is_single()) {	//投稿なら
			$single_post_id = get_the_id();//投稿IDを取得
			$mycats = get_the_terms( $single_post_id, 'plugins');//属するカスタムタクソノミー(plugins)のタームを取得
			if(is_array($mycats) && count($mycats)>0) {	//タームがあれば
				$mycat = $mycats[0]; //一つ目のタームを取得
				$plugins_name = $mycat->name; //ターム名
				$plugins_slug = $mycat->slug; //タームスラッグ
			}
			
			if ($map_area_name) { //ターム名が設定されていたら
			
				//一番右のパンくずを$trail_add[0]にコピー
				$trail_add[0] = $bcnObj->trail[0];

				//独自ページのパンくず生成
				$bcnObj->trail[0] = clone $bcnObj->trail[0];//クローンで初期化
				
				$bcnObj->trail[0]->set_title($plugins_name);//タイトルを設定
				
				$query = array('plugins' => $plugins_slug);//URLのパラメータを設定
				$seturl = add_query_arg( $query ,  home_url()) ;
				$bcnObj->trail[0]-> set_url($seturl);//カスタムタクソノミーのURLを設定
				
				$bcnObj->trail = array_merge ($trail_add, $bcnObj->trail);//マージ
			}
		}
	}
	return $bcnObj;
}

 

0