MySQL Incorrect string value: の解決策

MySQL である文字をInsertしようとしてエラーが発生。

Incorrect string value: '\xF0\xA6\x9A\xB0\xE7\x94...' for column 'name' at row 1

調べてみると、どうやら「サロゲートペア」である文字をInsertしようとしたからみたいでした。

結論からいうと、MySQL側のcharacter_set_serverをutf8mb4にすればいいようです。

my.iniの編集

my.iniの[mysqld]セクションにある

character_set_server=utf8

を、

character_set_server=utf8mb4

に変更します。(なければ追加)
変更できたらMySQLを再起動。
MySQLの再起動は、タスクマネージャーのサービスタブをクリックして、MySQLを探して右クリック→再起動(R) でできます。

1607170002

テーブルのキャラクターセットの変更

さらに、すでにあるテーブルのキャラクターセットを変更します。
次の例は、memberというテーブル名のキャラクターセットをutf8mb4に変更します。

 ALTER TABLE member CONVERT TO CHARACTER SET utf8mb4;


面倒ですけど、テーブル1つずつ変更しました。
一括して変更する方法もあるみたいですけど、変換に失敗することもあるので、確認しながらの方がいいと思います。

これで、Incorrect string value エラーは出なくなりました。

ちなみに、utf8mb4は、MySQL 5.5.3以降でなけらば使えないらしいので、しれより古いバージョンのMySQLを使っているのであれば、MySQL自身のバージョンアップが必要ってことになりますね。。。

JQuery リンクのHover時のデザインいろいろ

リンクタグの上にマウスを載せた時に、CSSだけではなく、JQueryでそれっぽくリンクを主張するいろいろ。

オンマウスで文字の色とリンクの背景を反転させる

色をanimateするには、JQueryUIが必要です。なので、HEADに以下を予め追加しておきます。

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>

これはリンクです。

jQuery(document).ready(function($){
    $("a span , .post a").on({
        "mouseenter": function(){
            //マウスオーバーで文字の色を白に。背景を赤に。
            $(this).stop().animate( { color:"#fff" , backgroundColor: "#f01d4f" }, 200);
        },
        "mouseleave": function(){
            //マウスオーバーで文字の色を白に。背景を赤に。
            $(this).stop().animate( { color:"#f01d4f" , backgroundColor: 'transparent' }, 200);
        }
    });
});

$("a span , .post a") としているのは、フロントページなどで特定のリンクだけに反映させたい部分には、aタグ内にspanで囲っておけばいいし、それ以外の投稿や固定ページでは、投稿者が意識しなくてもいいようにしたかったので。

マウスオーバーで薄くする

これはリンクです。

jQuery(document).ready(function($){
    $("a.fadeto").on({
        "mouseenter": function(){
            //マウスオーバーで透過率60%
            $(this).stop().fadeTo(100,0.6);
        },
        "mouseleave": function(){
            //マウスオーバーで透過率100%(透過なし)
            $(this).stop().fadeTo(100,1.0);
        }
    });
});

WordPressのダッシュボードにPHPバージョンを表示する

WordPressはPHPで動作していますが、そのバージョンによって、function.phpに書き込んだ内容が、エラーになったりならなかったりします。

なので、事前にPHPのバージョンを確認したいことがありますが、そんなときにはfunction.phpに以下を書き加えます。

function show_php_ver_dashboard_widget_function() {
    echo 'PHP version: ' . phpversion();
}

function show_php_ver_add_dashboard_widgets() {
    wp_add_dashboard_widget('show_php_ver_dashboard_widget', 'PHPのバージョン', 'show_php_ver_dashboard_widget_function');    
}
add_action('wp_dashboard_setup', 'show_php_ver_add_dashboard_widgets' );

ダッシュボードにPHPのバージョンが表示されるようになります。

echo 'PHP version: ' . phpversion();

の部分をいじれば、オリジナルのダッシュボードウィジェットが作れるっというわけでした。

C# DateTimePickerの値を非表示にする。

C#で、DateTimePickerをそのまま使うと、nullを入れられません。

なので、常に何かの値が入っているのですが、それは仕方がないとして、せめて非表示にしたい場合に次のようにします。

まず、フォームにDateTimePicker、dateTimePicker1を配置しているとします。
Form1にDateTimePickerを配置

DateTimePickerのvalueには、Nullが入らないので、代わりにDateTime? dateTime を値の入れ物として用意します。DateTime型もNull非許容型なので、?をつけてNull許容型にします。

dateTimePicker.Format の値を DateTimePickerFormat.Customにして、CustomFormat に半角の空白を入れると、日付が非表示になるので、これを利用します。

カレンダーで日付が設定されるなど数値が変更になったときには、イベントを発動して日付を表示させます。
そして、Deleteキーが押された時はdateTime変数をnullにして、DateTimePickerの数値を非表示にします。

DateTime? dateTime;

private void Form1_Load(object sender, EventArgs e)
{
 //イベントの追加
 this.dateTimePicker1.ValueChanged += new System.EventHandler(this.dateTimePicker1_ValueChanged);
 this.dateTimePicker1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.dateTimePicker1_KeyDown);

 //今日の日付を設定した場合
 //dateTime = DateTime.Today;
 //setDateTimePicker(dateTime);

 //nullを設定した場合
 dateTime = null;
 setDateTimePicker(dateTime);
}

private void dateTimePicker1_KeyDown(object sender, KeyEventArgs e)
{
 if (e.KeyData == Keys.Delete)
 {
 //Deleteキーが押されたら、dateTimeにnullを設定してdateTimePicker1を非表示に
 dateTime = null;
 setDateTimePicker(dateTime);
 }
}

private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
 //dateTimePicker1の値が変更されたら表示する
 dateTime = dateTimePicker1.Value;
 setDateTimePicker(dateTime);
}

private void setDateTimePicker(DateTime? datetime)
{
 if (datetime == null)
 {
 //DateTimePickerFormat.Custom にして、CostomFormatは半角の空白を入れておくと、日時が非表示になる。
 dateTimePicker1.Format = DateTimePickerFormat.Custom;
 dateTimePicker1.CustomFormat = " ";
 }
 else
 {
 //フォーマットを元に戻して、値をセットする。
 dateTimePicker1.Format = DateTimePickerFormat.Long;
 dateTimePicker1.Value = (DateTime)datetime;
 }
}

こんな感じで。ちゃんと日付が非表示になりますし、日付を設定すれば、表示されます。

日付が非表示になります。 日付を設定

C# iTextSharpで枠内に収まるようにテキストを出力

iTextSharpでSetSimpleColumnを使って、指定した枠内にテキストを収めたい場合、フォントサイズを小さくするしかありません。

そこで、徐々にフォントサイズを小さくしながら、枠内に収まるようにテキストを描画する方法です。
columnText.Go()で描画するのですが、columnText.Go(true)と引数にtrueを渡すことで、シミュレーションモドになります。で、戻り値をみると、枠内に文字が収まったかどうかがわかります。

もし、戻り値がColumnText.NO_MORE_COLUMNなら、枠外にはみ出ていることになります。
なので、戻り値がColumnText.NO_MORE_COLUMNである間は、フォントサイズを小さくしていくようにします。

ただし、フォントサイズがあまりにも小さいと見えなくなってしまうし、マイナスになると例外を発生するので、1.0f以下にはならないようにします。

以下のサンプルコードは、
using System.IO;
using iTextSharp.text.pdf;
using iTextSharp.text;
を必要とします。

//A4サイズを横向きで
Document pdfDocument = new Document(PageSize.A4.Rotate(), 0, 0, 0, 0);

//出力先のファイル名
string makePdfFilePath = @"c:\PDF\test.pdf";
FileStream fileStream = new FileStream(makePdfFilePath, FileMode.Create);
PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDocument, fileStream);

//パスワードで保護する場合
//string password = "pass";
//pdfWriter.SetEncryption(Encoding.ASCII.GetBytes(password), Encoding.ASCII.GetBytes(password),
//    PdfWriter.ALLOW_SCREENREADERS, PdfWriter.STANDARD_ENCRYPTION_128);

//PDFドキュメントを開く
pdfDocument.Open();

//フォント名
string fontName = "MS ゴシック";

//フォントスタイル。 複合するときは、&で。
int fontStyle = iTextSharp.text.Font.BOLD;// &iTextSharp.text.Font.ITALIC;

//フォントカラー
BaseColor baseColor = BaseColor.BLACK;

PdfContentByte pdfContentByte = pdfWriter.DirectContent;

//テンプレートとするPDF
//PdfReader pdfTemplateReader = new PdfReader(@"c:\PDF\BlankSheet.pdf"); 
//PdfImportedPage pdfTemplatePage = pdfWriter.GetImportedPage(pdfTemplateReader, 1);
//pdfContentByte.AddTemplate(pdfTemplatePage, 0, 0);

//フォントファイルのシステムフォルダを設定
FontFactory.RegisterDirectory(Environment.SystemDirectory.Replace("system32", "fonts"));

//出力するテキスト
string draw_text = "テキスト出力テキスト出力";

//文字間を指定
pdfContentByte.SetCharacterSpacing(0.1f);

//出力する位置
float draw_x = 50;
float draw_y = 50;
float draw_w = 150;
float draw_h = 20;

//四角を出力
//線の色を指定
pdfContentByte.SetRGBColorStroke(255, 0, 0);
//線の幅を指定
pdfContentByte.SetLineWidth(1.0f);
//線の種類(点線)を指定
pdfContentByte.SetLineDash(5.0f, 2.0f);
//範囲
pdfContentByte.Rectangle(draw_x, draw_y, draw_w, draw_h);
//描画
pdfContentByte.Stroke();

//範囲内に収まるようにフォントサイズを小さくしていく
for (float fontSize = 30.0f; fontSize > 0; fontSize--)
{
    //フォントの設定
    iTextSharp.text.Font font =
        FontFactory.GetFont(fontName,
        BaseFont.IDENTITY_H,            //横書き
        BaseFont.NOT_EMBEDDED,          //フォントを組み込まない
        fontSize,
        fontStyle,
        baseColor);

    
    ColumnText columnText = new ColumnText(pdfContentByte);

    //SetSimpleColumnで出力
    columnText.SetSimpleColumn(
        new Phrase(draw_text, font)
        , draw_x
        , draw_y
        , draw_x + draw_w
        , draw_y + draw_h
        , fontSize
        , Element.ALIGN_LEFT    //ちなみに、SetSimpleColumnでは、ALIGN_MIDDLE(縦方向の中寄せ)は使えない
        );

    //テキスト描画シミュレーション
    int result = columnText.Go(true);

    //もし、枠内に収まっていなければ、columnText.Go() の戻り値はColumnText.NO_MORE_COLUMNになる
    if (ColumnText.NO_MORE_COLUMN != result || fontSize <= 1.0f)
    {
        //再度、columnTextにテキストをセット
        columnText.SetSimpleColumn(
            new Phrase(draw_text, font)
            , draw_x
            , draw_y
            , draw_x + draw_w
            , draw_y + draw_h
            , fontSize
            , Element.ALIGN_LEFT
            );

        //テキスト描画
        columnText.Go();
        
        break;
    }
}

//PDFドキュメントを閉じる。
pdfDocument.Close();

説明のために、わざとつらつら書いてますが、ところどころ関数化しておくと便利です。

C# iTextSharpで日本語のPDFファイルを出力

PDFファイルを出力するライブラリにiTextSharpがあります。
JAVAライブラリだったiTextを.net用に移植されたものです。(ありがたい!)

iTextSharpを使って、日本語でPDFファイルを出力します。

iTextSharpの準備

まずは、VisualStudioの設定ですが、手軽にnuGetでいきます。

NuGetパッケージマネージャの起動

iTextSharpで検索すればすぐ見つかりますので、インストール。
iTextSharpで検索

OKをクリック。
1607100003

あとは、同意→閉じる で準備完了。

コーディング

まず、以下のサンプルを試す場合は、
using System.IO;
using iTextSharp.text.pdf;
using iTextSharp.text;
を入れておいてください。

テキストを描画する方法はたくさんあるのですが、一番シンプルな方法は次のようにします。ただし、この方法では描画する位置は自由に指定できませんし、日本語を出力できません。(多分)

            //A4サイズを横向きで
            Document pdfDocument = new Document(PageSize.A4.Rotate(), 0, 0, 0, 0);

            //出力先のファイル名
            string makePdfFilePath = @"c:\PDF\test.pdf";
            FileStream fileStream = new FileStream(makePdfFilePath, FileMode.Create);
            PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDocument, fileStream);

            //PDFドキュメントを開く
            pdfDocument.Open();

            pdfDocument.Add(new Paragraph("test"));
            
            //PDFドキュメントを閉じる
            pdfDocument.Close();

 

ShowTextでテキスト描画

今度は、任意の場所にテキストを配置する場合。
上と違って、PdfContentByte オブジェクトを先に用意して、MoveText(50, 50) で描画位置を指定しています。ちなみに、左下が(0,0)です。
pdfDocument.Add()で描画すると、左上から始まるくせに、左下が(0,0)とはなんぞ。という感じですが。

//A4サイズを横向きで
Document pdfDocument = new Document(PageSize.A4.Rotate(), 0, 0, 0, 0);

//出力先のファイル名
string makePdfFilePath = @"c:\PDF\test.pdf";
FileStream fileStream = new FileStream(makePdfFilePath, FileMode.Create);
PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDocument, fileStream);

//PDFドキュメントを開く
pdfDocument.Open();

string fontFolder = Environment.SystemDirectory.Replace("system32", "fonts");

//フォント名
string fontName = fontFolder + "\\msgothic.ttc,0";

//フォントカラー
BaseColor baseColor = BaseColor.BLACK;

//フォントサイズ
float fontSize = 30.0f;

PdfContentByte pdfContentByte = pdfWriter.DirectContent;

//フォントの準備
BaseFont baseFont = BaseFont.CreateFont(fontName, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

//テキスト描画開始
pdfContentByte.BeginText();

//フォントとフォントサイズの指定
pdfContentByte.SetFontAndSize(baseFont, fontSize);

//描画位置の指定
pdfContentByte.MoveText(50, 50);

//描画するテキスト
pdfContentByte.ShowText(new PdfTextArray("あいうえお"));
pdfContentByte.ShowText(new PdfTextArray("かきくけこ"));

//テキスト描画終了
pdfContentByte.EndText();

//PDFドキュメントを閉じる
pdfDocument.Close();

SimpleColumnを使って、任意の枠内にテキスト描画

ColumnTextのSetSimpleColumnメソッドを使えば、指定した枠内にテキストを描画できます。
フォントの指定方法を上の例ではFontBaseを使っていますが、以下ではFontFactoryでpdf.Fontを取得して指定しています。フォントはファイル名ではなくフォント名を指定します。

//A4サイズを横向きで
Document pdfDocument = new Document(PageSize.A4.Rotate(), 0, 0, 0, 0);

//出力先のファイル名
string makePdfFilePath = @"c:\PDF\test.pdf";
FileStream fileStream = new FileStream(makePdfFilePath, FileMode.Create);
PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDocument, fileStream);

//PDFドキュメントを開く
pdfDocument.Open();

//フォント名
string fontName = "MS ゴシック";

//フォントサイズ
float fontSize = 10.0f;

//フォントスタイル。 複合するときは、&で。
int fontStyle = iTextSharp.text.Font.BOLD;// &iTextSharp.text.Font.ITALIC;

//フォントカラー
BaseColor baseColor = BaseColor.BLACK;

//Fontフォルダを指定
FontFactory.RegisterDirectory(Environment.SystemDirectory.Replace("system32", "fonts"));

//フォントの設定
iTextSharp.text.Font font =
    FontFactory.GetFont(fontName,
    BaseFont.IDENTITY_H,            //横書き
    BaseFont.NOT_EMBEDDED,          //フォントを組み込まない
    fontSize,
    fontStyle,
    baseColor);

PdfContentByte pdfContentByte = pdfWriter.DirectContent;

ColumnText columnText = new ColumnText(pdfContentByte);

//SetSimpleColumnで出力
columnText.SetSimpleColumn(
    new Phrase("あいうえおかきくけこ", font)
    , 50    // X1位置
    , 50    // Y1位置
    , 100   // X2位置
    , 70    // Y2位置
    , fontSize
    , Element.ALIGN_LEFT    //ちなみに、SetSimpleColumnでは、ALIGN_MIDDLE(縦方向の中寄せ)は使えない
    );

//テキスト描画
columnText.Go();

//PDFドキュメントを閉じる
pdfDocument.Close();

 

C# 配列やListで任意の範囲を合計したり、平均出したり。

配列で、合計を出したければ Sum()、平均を出したければ Average() メソッドが便利ですが、配列の特定の範囲だけを対象にしたい場合。

Array.Copy()で任意の範囲を抜き出す

たとえば、次のように8つの要素がある配列の2番目から5つの要素の合計や、平均を求めたい場合、Array.Copy()を使って、一旦別の配列に抜き出してから、その配列を合計、平均すればいいです。

  int[] a = new int[] { 85, 76, 68, 79, 82, 65, 72, 74 };

 //int型の配列の合計
 int a_sum = a.Sum();

 //int型の配列の平均
 double a_avg = a.Average();

 
 //配列の1つ目から5つを抜き出す
 int[] b = new int[5];
 Array.Copy(a, 1, b, 0, 5);

 //抜き出したint型の配列の合計
 int b_sum = b.Sum();

 //抜き出したint型の配列の平均
 double b_avg = b.Average();

上の例では、Array.Copy(c, 1, d, 0, 5); で、List<int> c の1つ目から配列のコピーを、bのはじめ(0)から5つ分配置する。ということになります。

List型ではCopyTo()で同様に処理できる

ところが、Array.Copy()はプリミティブ型(基本形)の配列しか扱えません。
でも、List型のようなCollection系の配列の場合、CopyTo()が使えるので同じように処理できます。

以下の例では、

  List<int> c = new List<int> { 85, 76, 68, 79, 82, 65, 72, 74 };

 //List<int>型の合計
 int c_sum = c.Sum();

 //List<int>型の平均
 double c_ave = c.Average();

 int[] d = new int[5];

 c.CopyTo(1, d, 0, 5);

 //抜き出したint型の配列の合計
 int d_sum = d.Sum();

 //抜き出したint型の配列の平均
 double d_avg = d.Average();

a.CopyTo(1, b, 0, 5); で、List<int> a の1つ目から配列のコピーを、bのはじめ(0)から5つ分配置する。ということになります。

似てますけど、微妙に違うので混乱してしまいそうなのでメモ。

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;

とすれば変換できます。

 

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"))
{
    //処理
}

簡単ですな。

 

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