DOBON.NETプログラミング道掲示板

■ 「新規作成」から投稿できます。
■ マルチポストされた投稿を見つけたときは、その投稿に返信することによりご報告ください。その際は匿名で投稿し、マルチポストされている場所を併記してください。
■ スパム対策のため、メールアドレスの先頭に"_"という文字が付加されています。
RSS 2.0 RSS 2.0 | RSS 0.91 | 携帯電話用 | 自分専用のアイコンを使用するには | 掲示板への要望 | 管理人に連絡 | お気楽掲示板
■ 24時間以内に作成されたスレッドは New で表示されます。
■ 24時間以内に更新されたスレッドは UpDate で表示されます。

記事リスト ( )内の数字はレス数
Nomal参照dllへの文字列引数をutf8で渡したい。(13) | NomalFILE.COPYでIOExceptionエラーが出る(11) | Nomalリストを別フォームに渡す方法(9) | Nomal例外発生した場合に変数をcatchに渡したい(9) | NomalCode128でバーコードが読み取れない(8) | Nomalモードレスフォーム Warning IDE0067を回避したい(7) | NomalIE11では表示されるが、.netのWebBrowserでは、表示されないHPを表示する方法(7) | Nomal数字だけで構成されてるCSVフィールドが自動的に数値として解釈される(7) | NomalフォームコントロールへのDataBindingsでプロパティが相互反映されない(7) | Nomal起動ディスプレイの指定方法について(6) | NomalListBoxにデータが表示されない(6) | Nomal文字列を8bit に戻してから UTF-8 に変換する方法(6) | NomalSQLServerテーブル内容をDataGridViewに表示するコードについて(6) | Nomal文字列構造体のListのソート(6) | NomalWebBrowser Controlを使って、任意の値を取得(5) | Nomalこんな演算子初めて見ました。(5) | NomalRichTextBoxで入力文字の自動折り返しを止めたい(5) | NomalあるWindows10PCでビルドしたEXEがW8.1以下で実行エラー(5) | Nomalポルトガル語の登録(5) | Nomaloo4oのAddTableをADOに移行したい(5) | NomalDeclare宣言するdllと参照追加をするdllの区別(4) | NomalVS2017で作成されたDLLをVS2005で作成されたAPで使用する方法(4) | Nomalフォルダ内の全ての容量を取得したい(4) | Nomal共変性と反変性ってこういうこと?(4) | Nomalプロセスからウインドウを取得(4) | NomalNewの使い方間違ってますか?(4) | Nomalユーザーコントロール内のテキストボックスのmodifiedプロパティ(4) | NomalJOIN操作の構文エラー(4) | Nomal動的にプロパティや変数の値の取得(4) | NomalVB6 ほかのアプリケーションを起動し そのアプリケーションは終了させる方法(4) | Nomalスクロールバーが出た時に高さを変えたい(4) | NomalDatagridViewの行高さ変更について(4) | NomalLINQのメソッド構文の書き方(3) | Nomalvb.net+SQLiteで複数データベースファイルへのトランザクション方法(3) | Nomalジェネリック型インターフェースを使った変数を扱いたい(3) | NomalProcess.WaitForExitで正常に動作しない?(3) | NomalPictureBox.Locationのキャンセル(3) | NomalCatch時のex.StackTraceの情報(3) | NomalVisualStudioでマクロ(3) | NomalOracleDataAccess を参照したプログラムでデバッグモードが機能しなくなる(3) | NomalVisualStudioでExcelのVSTO開発(3) | NomalVB.NETでCSVを読み込む際にSQL文を使いたい(3) | NomalDrawImage でメモリ不足エラー(3) | NomalVb.netからAccessへの接続について(3) | Nomal令和の日付への対応(3) | NomalHTTP 417エラーを発生させるためのIIS設定はどうすればよいか(3) | NomalDrawString前のFillRectangle有無により文字の太さが違う理由について教えて下さい(3) | NomalPIctureBox同士を論理合成したい(3) | Nomalデータセット定義ファイルからDataTable(3) | Nomalネットの画像の複数枚を重ね合わせたい(3) | NomalDataGridViewで検索をかける方法(3) | NomalDataGridViewの選択時の色を透明にしたい(3) | NomalWebBrowserでWebページからのメッセージ(3) | NomalASP.NETから呼ばれているかどうか判定する方法(3) | NomalCA2213の警告が消えません(3) | NomalC# 現在のコンテキスト内にxxxという文字は存在しませんと出ます(3) | NomalTaskクラスを.NET Framework 2.0で実現させる方法(2) | NomalWebBrowser Control foreachで値が消える(2) | NomalEditボックスに簡体字をセットする方法(2) | NomalWebClientが上手く動かない(2) | Nomalフォーム外のカーソルの変更(2) | Nomalラムダ式の勉強中(2) | NomalRichTextBoxで入力文字の自動折り返しを止めたい(2) | NomalC#をVBに変換(2) | NomalWebClientで、短期間にDownloadStringAsyncを実行したい(2) | NomalマウスのないOSでマウスカーソルの表示(2) | NomalToolStripMenuItemにShortcutKeysを指定した際の、元のコントロールを取得する方法(2) | NomalMouseEventArgsのカレント座標(2) | Nomalリッチテキストボックスでの字間の調整(2) | NomalVC++ → VB.Netに変換時に文法エラー(2) | NomalSQL-Server Compact 4.0が表示されない(2) | Nomalバーコードの数字を非表示にしたい(2) | Nomal自作したアプリの発行元を明記したい(2) | NomalSystem.Threading.Thread.Sleep()と変数(2) | NomalDataGridView 行の背景色の設定(2) | NomalDatagridviewのクリア(2) | NomalnumericUpDwonコントロールのvalue(2) | NomalVisual Studio DataTableの値のアクセスの仕方(2) | NomalDataTableの構造が同じか調べるメソッド(2) | NomalRejectChangesについて(2) | NomalPC機種によってスタートアップ画面が中央から左上にずれる、Fontがおかしくなる。(2) | Nomalタスクスケジュール登録時の例外メッセージ(2) | Nomal管理者モードでクリック(2) | NomalVB2017でのインストーラ作成時のエラーについて(2) | NomalMicrosoft Azure OCRのサンプルコード実行時エラー(2) | Nomalデータバインド時のDataGridViewのカスタムソート(2) | NomalObject型からDecimalへの変換(2) | Nomal擬似言語をVBのプログラミングに変換(2) | Nomalユーザーコントロールのプロパティが保存されない(2) | NomalWindows10(1803)からGetHostEntryでipv4が取得出来ない場合がある(2) | Nomal自分自身を呼び出すのはOKですか(1) | NomalList型でエラーが起きてしまい・・・(1) | NomalLINQの拡張メソッドの定義(1) | NomalWebRequest でメモリが解放されない(1) | NomalFunction プロシージャからの文字選択(1) | NomalRDP接続でのネットワーク帯域制限(0) | Nomal必須コンポーネントの一覧に追加したい(0) | NomalApp.configのMy.Application.Log設定で使用できない属性が出る(0) | Nomalvb2010を使用したmicrosoft Wordの任意の行の削除(0) | NomalWinFormsでWindows10のカメラアプリと連携したい(0) |



■記事リスト / ▼下のスレッド
■34184 / 親記事)  ListBoxにデータが表示されない
□投稿者/ ケミカル 一般人(1回)-(2019/03/07(Thu) 11:46:23)
  • アイコン環境/言語:[c# vs2015] 
    分類:[.NET] 

    ListBox1、ListBox2というListBoxが2つあり、それぞれのDataSourceがDataTableになっています。

    ListBox1.DataSource = dataTable1
    ListBox2.DataSource = dataTable2

    ボタンを押すと、ListBox1に表示されているデータがListBox2に移るようにプログラムを組んでいます。

    お伺いしたいのは、

    dataTable2.cleear();をした後にボタンを押してもListBox2にデータが何も表示されません。
    dataTable2の中身を確認すると、正しくdataTable2に保存されていあました。
    ListBox2にデータが表示されるようにするにはどうしたらいいでしょうか?
違反を報告
引用返信

▽[全レス6件(ResNo.2-6 表示)]
■34186 / ResNo.2)  Re[2]: ListBoxにデータが表示されない
□投稿者/ ケミカル 一般人(2回)-(2019/03/07(Thu) 16:40:43)
  • アイコン
    dataTable2.Rows.Clear(); ではなくdataTable2.Clear(); でした。失礼しました。
    型付DataSetです。そして、dataTable2.Clear();のせいで希望通りの動きにならないと
    思っていましたが間違いでした。これは問題ありませんでした。
    
    問題になっているのは、追記しました「button3」の箇所でした。
    データベースに問合せをして、データが存在していれば、引き続き
    button2を押しても正しくdataTable2にデータが追加されListBox2にもデータが表示されていました。
    
    しかし、データベースにデータがなかった場合、button2を押すと
    dataTable2にはデータは追記されるものの(ブレイクポイントを設定して中身を見ています)、
    ListBox2には値が表示されませんでした。
    
    using System;
    using System.Data;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            DataTable dataTable1;
            DataTable dataTable2;
            private void Form1_Load(object sender, EventArgs e)
            {
                dataTable1 = new DataSet("DataSet1").Tables.Add("DataTable1");
                dataTable2 = new DataSet("DataSet1").Tables.Add("DataTable1");
                dataTable1.Columns.Add("DataColumn1");
                dataTable2.Columns.Add("DataColumn1");
    
                dataTable1.Rows.Add("aaa");
                dataTable1.Rows.Add("bbb");
                dataTable1.Rows.Add("ccc");
                dataTable1.AcceptChanges();
    
                dataTable2.Rows.Add("xxx");
                dataTable2.AcceptChanges();
    
                listBox1.DataSource = dataTable1;
                listBox1.DisplayMember = "DataColumn1";
                listBox2.DisplayMember = "DataColumn1";
                listBox2.DataSource = dataTable2;
            }
    
            private void button1_Click_1(object sender, EventArgs e)
            {
                dataTable2.Rows.Clear();
            }
    
            private void button2_Click_1(object sender, EventArgs e)
            {
                dataTable2.Rows.Add("TEST" + DateTime.Now.Ticks);
            }
    
            private void button3_Click(object sender, EventArgs e)
            {
                //DB接続部分省略
                var strSQL = "select * from table where col = '100'";
    
                using (SQLCommand command = new SQLCommand(sql, connection))
                {
                    using (SQLDataAdapter adp = new SQLDataAdapter())
                    {
                        adp.SelectCommand = command;
                        adp.Fill(dataTable2);
                    }
                }
            }
        }
    }
    

違反を報告
引用返信
■34187 / ResNo.3)  Re[3]: ListBoxにデータが表示されない
□投稿者/ 魔界の仮面弁士 大御所(1217回)-(2019/03/07(Thu) 17:34:07)
  • アイコン2019/03/08(Fri) 23:35:48 編集(投稿者)

    No34186に返信(ケミカルさんの記事)
    > dataTable2.Rows.Clear(); ではなくdataTable2.Clear(); でした。失礼しました。

    ということは、型付 DataSet であることになりますね。

    <追記>
    ごめんなさい。何か勘違いしていたようです。
    型付きかどうかに関わらず、
     dataTable2.Clear();
     dataTable2.Rows.Clear();
    のいずれの構文も使えるのでした。
    (厳密には異なる処理だが、ほぼ同じ結果になる)
    </追記>


    > 型付DataSetです。

    型付 DataSet ではあるけれど、データの取得には
    TableAdapter を用いておらず、
    DataAdapter を使っているのでしょうか?


    > using (SQLCommand command = new SQLCommand(sql, connection))
    SQLCommand というのは、
    SqlCommand のことでしょうか?
    (System.Data.SqlClient.SqlCommand クラス)



    > 問題になっているのは、追記しました「button3」の箇所でした。

    う〜ん。まだ食い違いがあるような…。

    新たに提示いただいたコードだと、私のコードそのままに、
    > DataTable dataTable2;
    のように、「型付ではない System.Data.DataTable」型の変数が使われています。

    型付 DataSet だというのであれば、変数宣言は
     DataSet1.DataTable1DataTable dataTable1;
     DataSet1.DataTable1DataTable dataTable2;
    のようになるはずですし、インスタンス生成も
     dataTable1 = new DataSet1().DataTable1; // dataTable1.DataSet != null にする場合
     dataTable2 = new DataSet1.DataTable1DataTable(); // dataTable2.DataSet == null にする場合
    などとなっているはず…。


    > //DB接続部分省略
    「adp.Fill(dataTable2);」 の前に dataTable2 をクリアする処理がありませんね。

    手元の環境で試してみましたが、button1 を押さずに button3 を何度も押した場合、
    データが無ければ、listBox2 の内容は変化しません。(増加も減少もしない)

    データが存在していた場合は、ボタンを押すたびに、
    listBox2 の行数がどんどん増えていきました。
    (DataTable に PrimaryKey 制約がある場合は、もちろんエラーになります)


    > dataTable2にはデータは追記されるものの(ブレイクポイントを設定して中身を見ています)、
    > ListBox2には値が表示されませんでした。

    前回の回答の繰り返しになってしまいますが、
    Form1_Load で listBox2.DataSource に割り当てた「dataTable2 変数」が持つインスタンスと、
    button3_Click で adp.Fill した際の「dataTable2 変数」」が持つインスタンスが、
    別のオブジェクトになっている可能性はありませんか?
違反を報告
引用返信
■34189 / ResNo.4)  Re[4]: ListBoxにデータが表示されない
□投稿者/ ケミカル 一般人(3回)-(2019/03/08(Fri) 18:11:29)
  • アイコン
    何度もすいません。実際のコードは下記にあるような感じになっています。
    Load時にデータベースにはデータがあるものとして、ListBox1にはデータが
    表示されます。
    
    @こちらは正しく動きます。
    ・Button1を実行
    ・Button2を実行(データベースにデータが存在する場合、ListBox2にデータが表示される)
    ・Button1を実行
    ・ListBox2に追加でデータが表示されます
    
    Aこちらは正しく動きません
    ・Button1を実行
    ・Button2を実行(データベースにデータが存在しない場合、ListBo2にデータは何も表示されない)
    ・Button1を実行
    ・ListBox2に追加でデータが表示されない。ただし、実際にはdataTable2にデータは格納されている。
    
    using System;
    using System.Data;
    using System.Windows.Forms;
    using System.Data.SqlClient;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            //----------------------------
            // dataTable1の構造とDataTable2の構造は違います。
    
    
            public Form1()
            {
                InitializeComponent();
            }
    
            //普通のDataTable
            DataTable dataTable1 = new DataTable();
            //型付データセット
            DataTable dataTable2 = new DataSet().Table;
    
            //Formロード
            private void Form1_Load(object sender, EventArgs e)
            {
                //リストボックスに表示
                var strSql = @"SELECT * FROM T where col1 = 'X'";
                dataTable1 = DoSomething.selectSQL(strSql);
                listBox1.DataSource = dataTable1;
                listBox1.DisplayMember = "column1";
    
                listBox2.DataSource = dataTable2;
                listBox2.DisplayMember = "column1";
            }
    
            //選択されたListBox1の値をListBox2に表示させる
            private void button1_Click_1(object sender, EventArgs e)
            {
                var row = listBox1.SelectedItem as DataRowView;
                dataTable2.Rows.Add(row["column1"].ToString());
            }
    
            //ListBox2に新しくデータをセットする
            private void button2_Click_1(object sender, EventArgs e)
            {
                var strSql = @"SELECT * FROM T where col1 = 'Y'";
                dataTable2.Clear();
                dataTable2 = DoSomething.selectSQL(strSql);
                listBox2.DataSource = dataTable2;
                listBox2.DisplayMember = "column1";
            }
        }
    
            class DoSomething  //こちらはClassファイルとして別で本当は持っています
            {
                public static DataTable selectSQL(string sql)
                {
                    DataTable dt = new DataTable();
    
                    using (var con = new SqlConnection("Data Source = datasource"))
                    {
                        con.Open();
                        using (SqlCommand command = new SqlCommand(sql, con))
                        {
                            using (SqlDataAdapter adapter = new SqlDataAdapter())
                            {
                  //実行時にDBにデータが無いとButton2を押してもデータがListBox2に表示されない
                                adapter.SelectCommand = command;
                                adapter.Fill(dt);
                                return dt;
                            }
                        }
                    }
                }
            }
    }

違反を報告
引用返信
■34190 / ResNo.5)  Re[5]: ListBoxにデータが表示されない
□投稿者/ 魔界の仮面弁士 大御所(1218回)-(2019/03/08(Fri) 22:31:21)
  • アイコン2019/03/08(Fri) 23:23:18 編集(投稿者)

    No34189に返信(ケミカルさんの記事)
    > //普通のDataTable
    > DataTable dataTable1 = new DataTable();
    > //型付データセット
    > DataTable dataTable2 = new DataSet().Table;

    なるほど、データセットクラス名が "DataSet" なんですね。
    ちょっと混乱してしまいました。(^^;

    System.Data 名前空間の DataSet なのか
    WindowsFormsApplication1 名前空間の DataSet なのか
    分かりにくくなるので、混同されないような名前付けをお奨めします


    結論から言えば、最初の回答でも述べた通り、
    『インスタンス管理』に問題があったようです。

    これは要するに、
     example.FillData(dataTable2);
    という操作と
     dataTable2 = example.GetData();
    という操作の違いです。


    前者は、既存の DataTable インスタンスを渡して、
    その器にデータを埋め込んでもらう処理。

    後者はデータの入った新しい DataTable インスタンスを作ってもらい、
    その新しい器を戻り値として受け取る処理です。


    では、提示頂いたコードで見てみましょう。

    > DataTable dataTable1 = new DataTable();
    > DataTable dataTable2 = new DataSet().Table;

    フィールド変数の dataTable1/2 には、new Form1() されたと同時に、
    DataTable のインスタンスが new されて保持されます。
    ここまでは良いですよね?


    > //ListBox2に新しくデータをセットする
    > private void button2_Click_1(object sender, EventArgs e)
    > {
    >  var strSql = @"SELECT * FROM T where col1 = 'Y'";
    >  dataTable2.Clear();
    そしてここで Clear しているのも、同じ器に対する操作です。
    ここまでは問題ありません。


    >  dataTable2 = DoSomething.selectSQL(strSql);
    問題はここ。

    dataTable2 が持っていた古いインスタンスは捨てられて、
    selectSQL から得た別のインスタンスへの参照に置き換えられています。

    この場合は本来、
     var newTbl = DoSomething.selectSQL(strSql);
     dataTable2.Merge(dataTable2, true);
    などとした方が良いでしょう。

    あるいは『DoSomething.FillBySQL(dataTable2, strSql);』となるような
    メソッドを用意するのもお奨めです。



    >  listBox2.DataSource = dataTable2;
    >  listBox2.DisplayMember = "column1";
    > }
    上記のバインド操作は Form1_Load で既に行っていますので、
    本来であれば、あらためてバインドし直す必要はありませんでした。

    しかし現状、再バインドが必要になってしまっているのは、
    同一の器(DataTable インスタンス)を使いまわしているのではなく、
    データを取得するたびに、新しい器を生成してしまっているためです。

    器が変わったので、ListBox のバインド先も切り替えねばならなかったという罠。


    もしも器を使いまわさず、毎回作り直すことを想定しているのなら、
    そもそも事前の Clear は冗長であり無意味です。

     // dataTable2.Clear();
     dataTable2 = DoSomething.selectSQL(strSql);
     listBox2.DataSource = dataTable2;
     listBox2.DisplayMember = "column1";



    個人的には、同じインスタンスを使いまわす実装にすることをお奨めします。
    バインド先を変更すると、ListBox の選択状態もリセットされてしまいますしね。



    > //普通のDataTable
    > DataTable dataTable1 = new DataTable();
    > //型付データセット
    > DataTable dataTable2 = new DataSet().Table;

    ところで上記のコード。

    折角の型付きなのですから、後者は本来
     DataSet.TableDataTable dataTable2 = new DataSet().Table;
    となるものです。

    提示頂いたコードの場合、名前空間を省略せずに記載すると
     global::System.Data.DataTable dataTable1 = new global::System.Data.DataTable();
     global::System.Data.DataTable dataTable2 = new global::WindowsFormsApplication1.DataSet().Table;
     //global::WindowsFormsApplication1.DataSet.TableDataTable dataTable2 = new global::WindowsFormsApplication1.DataSet().Table;
    という意味になり、型付きのメリットが半減してしまいそう。

    現状では、DoSomething 側も型付を意識した設計にはなっていないので、
    型付きではない DataTable で受けるしかなかったのでしょうけれども、
    今回提示した形で修正すれば、型付の方で扱えるようになると思います。
違反を報告
引用返信
■34192 / ResNo.6)  Re[6]: ListBoxにデータが表示されない
□投稿者/ ケミカル 一般人(4回)-(2019/03/11(Mon) 18:21:56)
  • アイコン>var newTbl = DoSomething.selectSQL(strSql);
    >dataTable2.Merge(dataTable2, true);

    dataTable2.Merge(newTbl, true);で解決する事ができました。

    色々と勘違いしていた部分があり勉強になりました。ありがとうございます。
解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-6]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■34079 / 親記事)  文字列を8bit に戻してから UTF-8 に変換する方法
□投稿者/ sato 一般人(1回)-(2019/01/04(Fri) 13:29:42)
  • アイコン環境/言語:[windows10 MicrosoftVisualStudio Community2017] 
    分類:[.NET] 

    例えば "漢字" という文字列の場合、UTF-8 では e6 bc a2 e5 ad 97 といったデータになりますが、「あるDLL」を用いて"漢字" という文字列を取得すると、00e6 00bc 00a2 00e5 00ad 0097 と 16bit 化してstring変数に格納しています。

    あるDLLの使い方としては、例えば、
    Dim str1 As String=「あるDLL("漢字")」
    としたとき、変数str1の内容が、00e6 00bc 00a2 00e5 00ad 0097 となります。

    「あるDLL」のヘルプによりますと、「 8bit に戻してから UTF-8 として扱います。ユーザーが独自にデコードする場合、バイト文字列に戻してから文字コードを UTF-8 として扱ってください。」とありました。

    そこで、以下のようなコードで試しましたが、変数str2の内容が文字化けになります。

    「バイト文字列に戻してから文字コードを UTF-8 」にする方法、ご教示いただけますでしょうか?
    よろしくお願いします。


    Dim str1 As String=「あるDLL("漢字")」

    Dim bytesData As Byte() = System.Text.Encoding.UTF8.GetBytes(str1)
    Dim str2 As String = System.Text.Encoding.UTF8.GetString(bytesData)


違反を報告
引用返信

▽[全レス6件(ResNo.2-6 表示)]
■34081 / ResNo.2)  Re[2]: 文字列を8bit に戻してから UTF-8 に変換する方法
□投稿者/ sato 一般人(2回)-(2019/01/04(Fri) 15:20:51)
  • アイコンNo34080に返信(Hongliangさんの記事)
    > 確認ですが、その「あるDLL」(の関数)で返される文字列は、
    > ・UTF-8でエンコードしたバイト配列を、
    > ・1バイトずつ区切って、
    > ・各バイトを16進4桁で表現し、
    > ・それぞれの前半2桁は00固定であり、
    > ・区切り文字には半角空白文字1文字を使用している
    > で問題ないですかね?
    お返事ありがとうございます。
    質問の文章が下手で、正確に伝えられていませんでした。お手数をおかけします。

    「あるDLL」(の関数)で返される文字列の文字コードを解析しますと、00e6 00bc 00a2 00e5 00ad 0097というコードで、文字列が「00e6 00bc・・・」というものではないです。
    この文字列を
    Using writer As StreamWriter = New StreamWriter("ファイル名.txt")
    writer.Write(str1)
    writer.Close()
    End Using
    で保存し、バイナリエディタで「ファイル名.txt」を開くと、00 e6 00 bc 00 a2 00 e5 00 ad となるということです。

    「あるDLL」(の関数)で返される文字列は、UTF-8 の 8bit データを UTF-16 の 16bit データとした文字列、という説明で伝わりますでしょうか?

    よろしくお願いします。



違反を報告
引用返信
■34082 / ResNo.3)  Re[3]: 文字列を8bit に戻してから UTF-8 に変換する方法
□投稿者/ Hongliang 大御所(548回)-(2019/01/06(Sun) 20:11:13)
  • アイコン
    StreamWriterは既定ではUTF-8で出力するのでそういう出力になることはあり得ませんが、 
    多分こういうことかなと思います。
    
    String.Join(" ", Array.ConvertAll(str1.ToCharArray(), Function (c) AscW(c).ToString("x4")))
    ' case1: 00e6 00bc 00a2 00e5 00ad 0097
    ' case2: 0000 00e6 0000 00bc 0000 00a2 0000 00e5 0000 00ad 0000 0097
    
    であればこんな感じになりますね。
    case1:
    Dim bytes As Byte() = Array.ConvertAll(str1.ToCharArray(), Function(c) CByte(AscW(c)))
    
    case2:
    Dim bytes As Byte() = str1.Where(Function (c, i) (i Mod 2) = 1).Select(Function(c) CByte(AscW(c))).ToArray()

違反を報告
引用返信
■34084 / ResNo.4)  Re[1]: 文字列を8bit に戻してから UTF-8 に変換する方法
□投稿者/ 魔界の仮面弁士 大御所(1186回)-(2019/01/07(Mon) 11:55:41)
  • アイコンNo34079に返信(satoさんの記事)
    > Dim str1 As String=「あるDLL("漢字")」
    > Dim bytesData As Byte() = System.Text.Encoding.UTF8.GetBytes(str1)
    > Dim str2 As String = System.Text.Encoding.UTF8.GetString(bytesData)

    Imports System.Text
    Imports System.IO
    Module Module1
     Sub Main()
      ' ここはテスト用のコードなので無視して OK
      Dim chars(5) As Char
      chars(0) = ChrW(&H00E6) 'U+00E6: Latin Small Letter Ae
      chars(1) = ChrW(&H00BC) 'U+00BC: Vulgar Fraction One Quarter
      chars(2) = ChrW(&H00A2) 'U+00A2: Cent Sign
      chars(3) = ChrW(&H00E5) 'U+00E5: Latin Small Letter A with Ring Above
      chars(4) = ChrW(&H00AD) 'U+00AD: Soft Hyphen (SHY)
      chars(5) = ChrW(&H0097) 'U+0097: <End of Guarded Area> (EPA)

      Dim str0 As String = New String(chars)
      MsgBox(str0, vbInformation)

      'Dim str1 As String=「あるDLL("漢字")」の代用
      Dim str1 As String = Encoding.Unicode.GetString(New Byte() {&HE6, &H0, &HBC, &H0, &HA2, &H0, &HE5, &H0, &HAD, &H0, &H97, &H0})

      'str0 と str1 が同じ文字列であることの確認
      MsgBox(str0.Equals(str1))

      'ファイルとして吐き出してみる
      Using writer As New StreamWriter("D:\utf-8.txt")
       writer.Write(str1)
       writer.Close()
      End Using
      Using writer As New StreamWriter("D:\utf-16.txt", False, New UnicodeEncoding(False, False))
       writer.Write(str1)
       writer.Close()
      End Using
      Using writer As New StreamWriter("D:\utf-16BE.txt", False, New UnicodeEncoding(True, False))
       writer.Write(str1)
       writer.Close()
      End Using


      '★ 本題:これでどうでしょう ★
      Dim str2 As String = Encoding.UTF8.GetString(str1.Select(Function(c) CByte(AscW(c))).ToArray())
      MsgBox(str2, vbInformation) '「漢字」
     End Sub
    End Module




    No34081に返信(satoさんの記事)
    > Using writer As StreamWriter = New StreamWriter("ファイル名.txt")
    > writer.Write(str1)
    上記の構文では、変数 str1 は As String または As Char() であり、
    かつ、StreamWriter は BOM 無しの UTF-8 エンコードであることを意味しますね。

    だとしたら
    > 00 e6 00 bc 00 a2 00 e5 00 ad となるということです。
    これはありえないはず。(末尾の 00 97 が欠落している点を抜きにしても)


    もしも本当に UTF-8 として保存された文字列データだとしたら、バイナリとしてみた際に
    &HE6 の後ろには &H80〜&HBF の範囲のバイナリが 2 つなければなりません。

    UTF-8 においては、各バイトの最上位ビットでマルチバイト文字かどうかが判断されるためです。
     U+0000〜U+007F は 00000000,0xxxxxxx → 1 バイト文字: &B0xxxxxxx
     U+0080〜U+07FF は 00000xxx,xxyyyyyy → 2 バイト文字: &B110xxxxx, &B10yyyyyy
     U+0800〜U+FFFF は xxxxyyyy,yyzzzzzz → 3 バイト文字: &B1110xxxx, &B10yyyyyy, &B10zzzzzz
    U+10000〜U+1FFFFFは 00000000,000wwwxx,xxxxyyyy,yyzzzzzzz → 4 バイト文字: &B11110www, &B10xxxxxx, &B10yyyyyy, &B10zzzzzz



    Imports System.Text
    Module Module1
     Sub Main()
      Dim rawBinary1 As Byte() = {&H0, &HE6, &H0, &HBC, &H0, &HA2, &H0, &HE5, &H0, &HAD, &H0, &H97}
      Dim rawBinary2 As Byte() = {&HE6, &H0, &HBC, &H0, &HA2, &H0, &HE5, &H0, &HAD, &H0, &H97, &H0}

      Dim enc1 = Encoding.GetEncoding("UTF-8", New EncoderExceptionFallback(), New DecoderExceptionFallback())
      Dim enc2 = Encoding.GetEncoding("UTF-16LE", New EncoderExceptionFallback(), New DecoderExceptionFallback())
      Dim enc3 = Encoding.GetEncoding("UTF-16BE", New EncoderExceptionFallback(), New DecoderExceptionFallback())

      For Each enc In {enc1, enc2, enc3}
       Console.WriteLine(enc.BodyName)
       For Each binary In {rawBinary1, rawBinary2}
        Try
         Console.WriteLine(enc.GetString(binary))
        Catch ex As DecoderFallbackException
         '★ UTF-8 として解釈すると、E6 の部分でデコードに失敗してしまう ★
         Console.Error.WriteLine(ex.Message)
        End Try
       Next
       Console.WriteLine("-------------")
      Next
      Console.ReadKey()
     End Sub
    End Module



    > 「あるDLL」を用いて"漢字" という文字列を取得すると、00e6 00bc 00a2 00e5 00ad 0097 と 16bit 化してstring変数に格納しています。
    > 「あるDLL」(の関数)で返される文字列は、UTF-8 の 8bit データを UTF-16 の 16bit データとした文字列、という説明で伝わりますでしょうか?
    "漢字" を UTF-8 でエンコードすると E6 BC A2 E5 AD 97 なので、それを 16bit 化しているわけですね。


    × StreamWriter で (既定の) UTF-8 として出力したときに「00 e6 00 bc 00 a2 ……」になる
    × StreamWriter で UTF-16 として出力したときに「00 e6 00 bc 00 a2 ……」になる
    ○ StreamWriter で UTF-16 として出力したときに「e6 00 bc 00 a2 00 ……」になる
    ○ StreamWriter で UTF-16 として出力したときに「00e6 00bc 00a2 ……」になる
違反を報告
引用返信
■34085 / ResNo.5)  Re[2]: 文字列を8bit に戻してから UTF-8 に変換する方法
□投稿者/ 魔界の仮面弁士 大御所(1187回)-(2019/01/07(Mon) 13:55:49)
  • アイコンNo34084に追記(魔界の仮面弁士の記事)
    > '★ 本題:これでどうでしょう ★
    > Dim str2 As String = Encoding.UTF8.GetString(str1.Select(Function(c) CByte(AscW(c))).ToArray())
    > MsgBox(str2, vbInformation) '「漢字」


    '☆ 念のため:エンディアンが逆だった場合 ☆
    Dim str2 As String = Encoding.UTF8.GetString(str1.Select(Function(c) CByte(AscW(c) >> 8)).ToArray())
違反を報告
引用返信
■34087 / ResNo.6)  Re[3]: 文字列を8bit に戻してから UTF-8 に変換する方法
□投稿者/ sato 一般人(3回)-(2019/01/09(Wed) 12:45:45)
  • アイコンHongliang 様
    魔界の仮面弁士 様

    ご教示、ありがとうございます。
    ase1:
    Dim bytes As Byte() = Array.ConvertAll(str1.ToCharArray(), Function(c) CByte(AscW(c)))

    Dim str2 As String = Encoding.UTF8.GetString(str1.Select(Function(c) CByte(AscW(c))).ToArray())

    両方のコード、どちらも、こちらの希望の通り動作しました。

    文字コードとその変換について理解が進んでいなく、また、説明がうまくなく、お手数をおかけしました。

    背景を簡単に説明します。
    「あるDLL」は、email受信用のDLLで、その関数はメール本文です。
    メールをeml形式で保存するのが目的です。
    そのDLLですが、送られてくるメールの文字コードがUTF8の場合、
    質問のような処理が必要とのことをでした。

解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-6]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■34049 / 親記事)  SQLServerテーブル内容をDataGridViewに表示するコードについて
□投稿者/ けい 一般人(14回)-(2018/11/30(Fri) 09:49:58)
  • アイコン環境/言語:[VB2015、Windows10、.NETFramework4.6] 
    分類:[.NET] 

    お世話になります。
    VB2015、Windows10、.NETFramework4.6で開発しています。

    SQLServerにあるテーブルの内容をSQL文で取得し、
    DataGridView1に表示するコードがあります。

    下記A〜Dをそれぞれ実行すると、
    Aはエラーになりますが、
    B〜Dは、
    表示上は同じ正常表示になります。

    どのパターンを使用しても問題ないでしょうか。
    不適切な書き方があれば教えてください。

    どうぞよろしくお願いします。

    Imports System.Data.SqlClient

    Dim cn As New SqlConnection(接続文字列)
    Dim strSQL As String
    Dim da As SqlDataAdapter
    Dim dt As DataTable
    Dim ds As DataSet
    strSQL = "(SELECT文)"
    da = New SqlDataAdapter(strSQL, cn)

    -----------------------------

    da.Fill(dt)


    dt=New DataTable
    da.Fill(dt)


    ds = New DataSet
    da.Fill(ds, "(テーブル名)")
    dt = ds.Tables("(テーブル名)")


    ds = New DataSet
    da.Fill(ds, "(テーブル名)")
    dt=New DataTable
    dt = ds.Tables("(テーブル名)")

    -----------------------------

    DataGridView1.DataSource = dt
違反を報告
引用返信

▽[全レス6件(ResNo.2-6 表示)]
■34052 / ResNo.2)  Re[2]: SQLServerテーブル内容をDataGridViewに表示するコードについて
□投稿者/ けい 一般人(15回)-(2018/11/30(Fri) 12:36:52)
  • アイコンNo34051に返信(魔界の仮面弁士さんの記事)

    お詳しいご説明をありがとうございます。

    Usingは使っているのですが、
    質問文をシンプルにするために、
    Dimにして掲載しました。

    運用上はB〜DいずれでもOKなのですね。
    個人的には、DataRowも使用することが多く、
    C、Dをよく使用しています。

    他者のコードを読んでいて、
    Bのパターンがあり、
    質問させていただきました。

    また、CとDとで、
    Newのあるなしで迷いました。

    アドバイスいただきました内容を参考に、
    研究してみます。

    (バージョン)

    そうなのですね。

    Windows8のPCに、VB2015をインストールして、
    Windows10にアップデイトしたから、でしょうか。
    バージョンは下記のようになっています。

    Windows10:1803
    Visual Studio Professional 2015:14.0.23107.0 D14REL
    .NET Framework:4.7.03056

    ただ、プロジェクトのプロパティを開き、フレームワークのコンボボックスを開くと、選択可能なバージョンは、4.6.1まで、なんですよね。

    色々調べてみます。

    ありがとうございます。
違反を報告
引用返信
■34053 / ResNo.3)  Re[2]: SQLServerテーブル内容をDataGridViewに表示するコードについて
□投稿者/ けい 一般人(16回)-(2018/11/30(Fri) 12:57:33)
  • アイコンNo34051に返信(魔界の仮面弁士さんの記事)

    失礼します。

    下記のリンクの方法で、インストールされているフレームワークのバージョンを見ると、4.7.2でした。

    インストールされている .NET Framework バージョンを確認する
    https://docs.microsoft.com/ja-jp/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed

    ところが、コントロールパネルの、
    「プログラムのアンインストール又は変更」を開いてみますと、
    4.7.2が見当たりません。

    代わりに、以下のすべてが入っています。

    4.5…Multi-Targeting Pack(通常)(以下、MTP)
    4.5.1…SDK(通常、日本語)、MTP(通常、日本語)
    4.5.2…MTP(通常、日本語)
    4.6…SDK(通常、日本語)、MTP(通常、日本語)
    4.6.1…SDK(通常、日本語)、MTP(通常、日本語、ENU)

    .NET Version Manager(x64)1.0.0-beta5

    これがどういう状況なのか、明確には分かりません。

    引き続き調べてみます。

    ありがとうございます。

違反を報告
引用返信
■34054 / ResNo.4)  Re[3]: SQLServerテーブル内容をDataGridViewに表示するコードについて
□投稿者/ 魔界の仮面弁士 大御所(1176回)-(2018/11/30(Fri) 16:47:18)
  • アイコンNo34053に返信(けいさんの記事)
    > 「プログラムのアンインストール又は変更」を開いてみますと、
    > 4.7.2が見当たりません。

    そもそも Windows 8 以降では、.NET Framework が
    オペレーティング システム の必須コンポーネントとなっているため、
    個別にアンインストールすることができません。

    そのため、.NET Framework の更新バージョンがある場合にも、
    『プログラムのアンインストール又は変更』ではなく、
    『インストールされた更新プログラム』の方となります。
    https://docs.microsoft.com/ja-jp/dotnet/framework/install/troubleshoot-blocked-installations-and-uninstallations


    しかし .NET Framework 4.8 の Early Build を除けば、
    .NET Framework 4.7.2 が現時点の最新版ですので、いずれにせよ
    現時点では、更新プログラムの一覧にも記載されていない可能性が高いです。
    https://blogs.msdn.microsoft.com/dotnet/2018/11/28/announcing-net-framework-4-8-early-access-build-3694/


    なお、OS コンポーネントという性質上、確認するとすれば
    『プログラムのアンインストール又は変更』ではなく
    『Windows の機能の有効化または無効化』の方となりますが、
    これも ASP.NET 関連モジュールの有効化/無効化が行える程度であり、
    .NET Framework のアンインストールやバージョン確認目的には使えません。


    > 下記のリンクの方法で、インストールされているフレームワークのバージョンを見ると、4.7.2でした。

    そのはずです。

    Windows 10 version 1803 (April 2018 Update) に搭載されている
    .NET Framework バージョンは 4.7.2 なので、先の表とも一致しますよね。


    参考までに、オフラインインストーラーの場所も掲載しておきます。
    Windows 10 に 4.7.2 をインストールする場合、対象バージョンは
     Windows 10 version 1607 (Anniversary Update
     Windows 10 version 1703 (Creators Update
     Windows 10 version 1709 (Fall Creators Update)
    となります。(version 1803 / 1809 は既定で有効)
    https://support.microsoft.com/en-us/help/4054530/


    そのひとつ前の 4.7.1 の場合は、
     Windows 10 version 1607 Anniversary Update
     Windows 10 version 1511 Creators Update
    が対象です。(version 1709 は既定で有効)
    https://support.microsoft.com/en-us/help/4033342/


    最初に投稿いただいた 4.7 の場合は
     Windows 10 version 1607 Anniversary Update
    が対象です。(version 1703 は既定で有効)
    https://support.microsoft.com/en-us/help/3186497/



    > 4.7.2が見当たりません。

    .NET Framework 4.7.2 の入っているバージョンの Windows 10 環境であっても、
    4.7.2 Targting Pack が無ければ、4.7.2 向けの開発は行えません。

    逆に言えば、対応する Targting Pack を導入することで、
    将来バージョンの .NET Framework 開発にも対応できます。
    (Targting Pack に対応している Visual Studio は 2012 以降です)

    VS2012 / 2013 は 4.6.2 まで、
    VS2015 / 2017 は 4.7.2 までに対応します。
    https://dotnet.microsoft.com/download/visual-studio-sdks



    > 代わりに、以下のすべてが入っています。

    そこは『実行環境』と『開発環境』の違いですね。
    ランタイム バージョンが共存できるわけではありません。


    > 引き続き調べてみます。

    .NET 4.7.2 開発を行う場合には、
     (1) NDP472-DevPack-ENU.exe
     (2) NDP472-DevPack-JPN.exe
    の順でインストールする必要があるようです。

    ※VS2017 の場合。VS2015 は試していません。
違反を報告
引用返信
■34056 / ResNo.5)  Re[3]: SQLServerテーブル内容をDataGridViewに表示するコードについて
□投稿者/ 魔界の仮面弁士 大御所(1177回)-(2018/11/30(Fri) 17:22:24)
  • アイコンNo34052に返信(けいさんの記事)
    > また、CとDとで、
    > Newのあるなしで迷いました。

    D であっても、動作上は問題はありません。

    しかし D の New DataTable の行は無意味ですから、
    より適切なのは C の構文と言えますね。

    もしも Fill する前に DataTable のインスタンスが必要なのであれば、
     ds = New DataSet()
     dt1 = New DataTable("テーブル名1")
     ds.Tables.Add(dt1)
     da.Fill(dt);
    あるいは
     ds = New DataSet()
     dt2 = ds.Tables.Add("テーブル名2")
     da.Fill(dt2)
    とすることもできます。

    まぁ、事前に DataTable のインスタンスを作ってもあまり意味は無いので、
    通常は C(または B)パターンで良いかと思いますよ。


    場合によっては、事前に列まで定義済みの DataTabel を用意した上で、
    「da.MissingSchemaAction」や「da.MissingMappingAction」も
    指定してから Fill するということもできますが、
    事前の列定義が必要なら型付 DataSet を使った方が手っ取り早そうです。


    > da.Fill(ds, "(テーブル名)")
    これについては、da.Fill(ds) だけでもいけると思います。
    テーブル名は自動生成されたものになりますケド。
    (da.TableMappings の事前指定が無い場合)
違反を報告
引用返信
■34057 / ResNo.6)  Re[4]: SQLServerテーブル内容をDataGridViewに表示するコードについて
□投稿者/ けい 一般人(17回)-(2018/11/30(Fri) 19:03:42)
  • アイコンNo34056に返信(魔界の仮面弁士さんの記事)

    ありがとうございます。
    とても参考になり、助かりました。

    今後ともどうぞよろしくお願い申し上げます。
解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-6]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■34025 / 親記事)  文字列構造体のListのソート
□投稿者/ あおぞら 一般人(1回)-(2018/11/13(Tue) 14:30:58)
  • アイコン環境/言語:[Win10 64Bit  C#FormApp Framework4.6.1] 
    分類:[.NET] 

    文字列構造体のListのソートがしたいのですが、うまくいきません。
    
            public struct Items
            {
                public string itemName;
                public string value;
                public string unit;
                public string oder;
            };
            public List<Items> itemaList = new List<Items>();
    
    このitemListには20レコードのデータが必要な順番で入っているのですが、oderには
    1〜9と無視するデータを表す0が格納されており、この1〜9のならびでデータを取り出したい
    時もあります。そこで、
    
        var tes = from num in itemList
                      where int.Parse(num.oder) > 0 && int.Parse(num.oder) <= 9
                      select int.Parse(num.oder);
    
    としてみたのですが、上手く値を取得できませんでした。
    どうしたらoder順にデータを取り得だせるでしょうか。
    御教示ください。

違反を報告
引用返信

▽[全レス6件(ResNo.2-6 表示)]
■34027 / ResNo.2)  Re[2]: 文字列構造体のListのソート
□投稿者/ あおぞら 一般人(2回)-(2018/11/13(Tue) 15:21:34)
  • アイコンNo34026に返信(魔界の仮面弁士さんの記事)
    > ■No34025に返信(あおぞらさんの記事)
    >>文字列構造体のListのソートがしたいのですが、うまくいきません。
    > 文字列ソートですので、並び順は
    >  "2", "12", "123", "234"
    > ではなく、
    >  "12", "123", "2", "234"
    > になりますが、そこは大丈夫でしょうか。
    >
    >
    >>oderには1〜9と無視するデータを表す0が格納されており、
    > oder は int や char ではなく string なのですよね。
    >
    > ということは 0,1〜9 ではなく、"0","1"〜"9" の間違いであろうかと思いますが、
    > それ以外の値たとえば "" や null や "0xA" などは入らないという前提でよろしいでしょうか。
    >
    > 20 レコードのうち、orer 値が同じ値だった場合の並び順は何に従うのでしょうか。
    > List<> の格納順を維持するべきなのか、それともフィールドの内容で判断するのか、
    > 質問内容からははっきりしません。
    >
    > また、order が "0" だった場合、「そのデータは存在しないものとして、ソート結果から取り除く」のでしょうか。
    > それとも "0" なデータは「どうせ無視されるので、ソート結果の何番目にあっても気にしない」のでしょうか。
    >
    >
    >
    >>どうしたらoder順にデータを取り得だせるでしょうか。
    > orderby で。

    文字列で格納してありますが、数値として、(〇1>2>3・・・×1>12>2)ソートしたいのでInt.Parseを使っています。

    oder順で並べるときは20レコードのうち9レコードしか使わないので、oderが0の場合は検索結果に含めない、もしくは並べ替えができたらFor文で頭9回回すということを考えて後ろにつける、のどちらかがいいと考えています。

    orderby int.Parse(num.oder) を追加したのですが、Message = "入力文字列の形式が正しくありません。"とデバッガで怒られます。

違反を報告
引用返信
■34028 / ResNo.3)  Re[3]: 文字列構造体のListのソート
□投稿者/ 魔界の仮面弁士 大御所(1163回)-(2018/11/13(Tue) 15:35:11)
  • アイコン# 引用は適切に。全文引用は避けましょう。

    No34027に返信(あおぞらさんの記事)
    >>> public List<Items> itemaList = new List<Items>();
    > 文字列で格納してありますが、数値として、(〇1>2>3・・・×1>12>2)ソートしたいのでInt.Parseを使っています。
    itemaList ではなく itemList
    Int.Parse ではなく int.Parse ですね。

    数値扱いしたいのなら、Items クラスに
     public int Order { get { return int.Parse(oder); } }
    を付与しておくという手もありますね。

    しかし oder に関して言えば、"0", "1"〜"9" しかないなら、
    int にする必要は無いようにも思えます。


    > oderが0の場合は検索結果に含めない
    それは
     itemList.Where(o => o.oder != "0")
    で良いかと。


    > oder順で並べるときは20レコードのうち9レコードしか使わないので、
    oder の値が "1"〜"9" のものは同時には存在せず、
    残り 11 レコードの oder は、すべて "0" ということですね。
    (もしかしたら、20 レコードすべてが "0" の可能性もあるかもしれませんが)

    もし、oder の値が競合することがあり、その場合は List<> 順を維持したいなら、

     var r1 = itemList.Where(o => o.oder != "0")
      .Select((item, index) => new { item, index })
      .OrderBy(o => o.item.oder).ThenBy(o => o.index)
      .Select(o => o.item);

    などと記述することが出来ます。


    > orderby int.Parse(num.oder) を追加したのですが、
    oder が競合しない "1"〜"9" ということなので、int.Parse も不要で

    var q = from o in itemList where o.oder != "0" orderby o.oder select o;

    かな。
違反を報告
引用返信
■34029 / ResNo.4)  Re[4]: 文字列構造体のListのソート
□投稿者/ 魔界の仮面弁士 大御所(1164回)-(2018/11/13(Tue) 15:43:13)
  • アイコンNo34028に追記(魔界の仮面弁士の記事)
    >> orderby int.Parse(num.oder) を追加したのですが、
    > oder が競合しない "1"〜"9" ということなので、int.Parse も不要で
    > var q = from o in itemList where o.oder != "0" orderby o.oder select o;
    > かな。

    おまけ。"10" 以降の値もあるなら、int.Parse 付きでこう書きます。

    var r = from o in itemList
        let oder = int.Parse(o.oder)
        where oder != 0
        orderby oder
        select o;


    >> orderby int.Parse(num.oder) を追加したのですが、Message = "入力文字列の形式が正しくありません。"とデバッガで怒られます。

    C# のクエリ構文では、orderby 句の後に select 句が必須です。
    (メソッド構文の場合は、OrderBy 拡張メソッドで終わっても良いですが)

    VB は Order By の後に Select を書かずとも済むのですけれどね。
違反を報告
引用返信
■34030 / ResNo.5)  Re[4]: 文字列構造体のListのソート
□投稿者/ あおぞら 一般人(4回)-(2018/11/14(Wed) 10:28:04)
  • アイコンNo34028に返信(魔界の仮面弁士さんの記事)
    var tes = from o in itemList where o.oder != "" orderby o.oder select o;
      for (var w = 0; w < 9; w++) { itemList_o[w] = tes.ElementAt(w); }
    とすることでやりたいことができました。
    ありがとうございました!(不要データは0が入っているというのは勘違いでnullだったのでコードも変更しています。)
解決み!
違反を報告
引用返信
■34033 / ResNo.6)  Re[5]: 文字列構造体のListのソート
□投稿者/ 魔界の仮面弁士 大御所(1167回)-(2018/11/14(Wed) 11:06:54)
  • アイコンNo34030に返信(あおぞらさんの記事)
    > (不要データは0が入っているというのは勘違いでnullだったのでコードも変更しています。)

    ならば where o.oder != "" ではなく、o.oder != null なのでは。
    あるいは、where !string.IsNullOrEmpty(o.oder) とか。


    > var tes = from o in itemList where o.oder != "" orderby o.oder select o;
    >   for (var w = 0; w < 9; w++) { itemList_o[w] = tes.ElementAt(w); }
    > とすることでやりたいことができました。
    設定値が "1"〜"9" ではなく、"1"〜"7" だった場合に備えて、
    ElementAt よりも ElementAtOrDefault の方が良いと思います。


    あるいは、常に "1"〜"9" が一意に存在することが保証されているのなら、
    そもそもループで詰め替えず、
     Items[] itemArray_out = tes.ToArray();
     List<Items> itemList_out = tes.ToList();
    だけで済ませる手もあります。(インスタンス管理次第ですが)

    # 解決済みチェックは付けたままにしておきます。
解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-6]



■記事リスト / ▲上のスレッド
■34430 / 親記事)  WebBrowser Controlを使って、任意の値を取得
□投稿者/ げんむ 一般人(1回)-(2020/03/18(Wed) 21:43:36)
  • アイコン環境/言語:[c# vs2019 .net 4.52] 
    分類:[.NET] 

    <td>内容1</td>
    <td style="font-weight:bold;" nowrap><aa href="/abc.html"><img src="/y.png">内容2</aa></td>
    <td>内容3</td>
    <td style="font-weight:bold;" nowrap><aa href="/def.html"><img src="/y.png">内容4</aa></td>
    <td><aa href="/def.html">内容5</aa></td>
    
    
    このようなHTMLがあります。TDタグのstyle属性にfont-weight:bold;が指定されているlink先と要素を取得したいです。
    上のHTMLでは、/abc.htmlと内容2、/def.htmlと内容4という値を取得したいです。
    
    そこでWebBrowser Controlを使いわかるところまで書きました。
    
     HtmlElementCollection elems = webBrowser1.Document.GetElementsByTagName("td");
    foreach (HtmlElement elem in elems)
    {
    	Debug.WriteLine(elem.InnerText);
    	//Debug.WriteLine(elem.GetAttribute("style"));
    }
    
    わからない点は以下になります。
    問題1.
    elem.InnerTextは全てのTDタグの要素を取得してしまうので、どのようにstyleがfont-weight:bold;のものだけを取得すればいいのかわからないです。
    var x = elem.GetAttribute("style")としましたが、なんの値も取得できませんでした。
    
    問題2.
    hrefのリンク先を取得する方法がまったくわかりません。
    
    よろしくお願い致します。
    
    Aタグはaのところをaaにしています

違反を報告
引用返信

▽[全レス5件(ResNo.1-5 表示)]
■34431 / ResNo.1)  Re[1]: WebBrowser Controlを使って、任意の値を取得
□投稿者/ Hongliang 大御所(573回)-(2020/03/18(Wed) 22:16:59)
  • アイコン> 問題1.
    > elem.InnerTextは全てのTDタグの要素を取得してしまうので、どのようにstyleがfont-weight:bold;のものだけを取得すればいいのかわからないです。
    HtmlElementにはStyleプロパティが用意されています。

    > 問題2.
    > hrefのリンク先を取得する方法がまったくわかりません。
    とりあえず、アドレス自体はa要素を指すHtmlElementに対してGetAttribute("href")を行うことで取得できます。
    リンク先を取得というのは、abc.htmlやdef.htmlの中身をファイルや文字列として取得したいということでしょうか?
    cookieとかが要求されないのであれば、HttpClientクラスのGetStringAsyncとかを使えばいいですが。
違反を報告
引用返信
■34432 / ResNo.2)  Re[1]: WebBrowser Controlを使って、任意の値を取得
□投稿者/ 魔界の仮面弁士 大御所(1275回)-(2020/03/19(Thu) 09:48:39)
  • アイコン
    No34430に返信(げんむさんの記事)
    > そこでWebBrowser Controlを使いわかるところまで書きました。
    
    既定の IE7 モードのままでの利用でしょうか。
    それとも FEATURE_BROWSER_EMULATION を変更されているのでしょうか。
    
    
    > どのようにstyleがfont-weight:bold;のものだけを取得すればいいのかわからないです。
    
    td に対して font-weight が指定されていなかったとしても
    tr や table に対して font-weight:bold が割り当てられていた場合、
    セルのテキストは bold になる可能性があります。
    .css ファイルでスタイルが設定される場合もありますし。
    
    
    カスケーディングも考慮する必要がある場合には、
    getComputedStyle メソッドもしくは
    currentStyle プロパティを使用できます。
    
    
    dynamic w = webBrowser1.Document.Window.DomWindow;
    string[] values = { "bold", "700" };
    
    var q = from td in webBrowser1.Document.GetElementsByTagName("TD").OfType<HtmlElement>()
            /* let fontWeight = (string)((dynamic)td.DomElement).currentStyle.fontWeight */
            let fontWeight = (string)w.getComputedStyle(td.DomElement).fontWeight
            where values.Contains(fontWeight)
            let anchor = td.FirstChild
            where anchor != null && anchor.TagName == "A"
            select new
            {
                Link = anchor.GetAttribute("href"),
                Text = anchor.InnerText
            };
    
    var sb = new StringBuilder();
    foreach (var anchor in q)
    {
        sb.AppendLine(anchor.Link).AppendLine(anchor.Text).AppendLine();
    }
    MessageBox.Show(sb.ToString());

違反を報告
引用返信
■34433 / ResNo.3)  Re[2]: WebBrowser Controlを使って、任意の値を取得
□投稿者/ げんむ 一般人(3回)-(2020/03/19(Thu) 11:15:47)
  • アイコン
    > HtmlElementにはStyleプロパティが用意されています。
    ->styleプロパティで取得できました。
     
    >アドレス自体はa要素を指すHtmlElementに対してGetAttribute("href")を行うことで取得できます。
    ->リンク先を文字列で取得したかったのげ、GetAttributeで大丈夫でした。
    
    以下のコードで目的を達成はできました。
    
                HtmlElementCollection elems = webBrowser1.Document.GetElementsByTagName("td");
    
                foreach (HtmlElement elem in elems)
                {
                    string style = elem.Style;
    
                    if (!(string.IsNullOrEmpty(style)) && style.Contains("font-weight: bold;"))
                    {
                        HtmlElementCollection a = elem.GetElementsByTagName("A");
                        string href = a[0].GetAttribute("href");
                        Debug.WriteLine(style);
                        Debug.WriteLine(href);
                    }
                }
    
    ただ、
    HtmlElementCollection a = elem.GetElementsByTagName("A");
    string href = a[0].GetAttribute("href");
    の箇所が何か変な気がします。もっと上手な書き方はあるでしょうか?

違反を報告
引用返信
■34434 / ResNo.4)  Re[3]: WebBrowser Controlを使って、任意の値を取得
□投稿者/ 魔界の仮面弁士 大御所(1276回)-(2020/03/19(Thu) 14:06:03)
  • アイコンNo34433に返信(げんむさんの記事)
    > HtmlElementCollection a = elem.GetElementsByTagName("A");
    > string href = a[0].GetAttribute("href");
    > の箇所が何か変な気がします。

    どの点が気にかかりますか?

    もしも [0] でのアクセスが気になるという話なら、
    事前に『 if (a.length > 0)』の判定を付け加えてください。


    また、Microsoft HTML Object Library の併用でも良ければ、
    こういう書き方にもできます。

    var doc = (mshtml.HTMLDocument)webBrowser1.Document.DomDocument;
    foreach (mshtml.HTMLTableCell cell in doc.getElementsByTagName("TD"))
    {
      // if (cell.style.fontWeight == "bold")
      if ((cell.style.cssText ?? "").Contains("font-weight: bold;") )
      {
        var anchors = cell.getElementsByTagName("A");
        if (anchors.length > 0)
        {
          mshtml.HTMLAnchorElement a = anchors.item(0);
          Debug.WriteLine(a.href);
        }
      }
    }


    WebBrowser への表示が不要なら、HTMLAgencyPack と言う手も。

    https://html-agility-pack.net/
    https://www.nuget.org/packages/HtmlAgilityPack/
    https://www.atmarkit.co.jp/ait/articles/1501/27/news140.html
違反を報告
引用返信
■34435 / ResNo.5)  Re[2]: WebBrowser Controlを使って、任意の値を取得
□投稿者/ げんむ 一般人(4回)-(2020/03/19(Thu) 16:06:50)
  • アイコンありがとうございました。無事に解決しました!
解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-5]






Mode/  Pass/


- Child Tree -