C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.101955 の関連記事表示

<< 0 >>
■101955  ListBoxに表示する文字列を揃える方法
□投稿者/ 初心者 -(2023/05/19(Fri) 14:08:14)

    分類:[VB.NET/VB2005 以降] 

    VB初心者です。

    VB2005 .NETでwindowsアプリケーションを作成しています。
    ファイルデータの中から特定の情報のみを抽出して、左揃えでListBoxに表示させたいです。
    SHIFT-JISやUNICODE、UTFなどの様々な文字コードが混在しており、上手く左揃えで表示できません。

    様々な文字コードが混在しているデータを揃えてListBoxに表示させる方法を教えてください。
親記事 /過去ログ178より / 関連記事表示
削除チェック/

■101956  Re[1]: ListBoxに表示する文字列を揃える方法
□投稿者/ 魔界の仮面弁士 -(2023/05/19(Fri) 14:14:19)
    2023/05/19(Fri) 14:37:05 編集(投稿者)

    No101955 (初心者 さん) に返信
    > SHIFT-JISやUNICODE、UTFなどの様々な文字コードが混在しており、上手く左揃えで表示できません。
    文字コードは関係ないのでは?
    文字集合(CharSet)なら関係するかもしれませんが。


    それに「上手く左揃えで表示できません」とだけ仰られても、
    それがどういう状態になっていて、それをどうしたいのかが
    一切説明されていないので、具体的な対策を答えるのは難しいです。

    たとえば WinForms において ListBox1.Items.Add("文字列") と書いた場合
    MultiColumn が True / False のいずれであったとしても、
    それぞれの項目は既定で左寄せで記述されるはずなので、
    「うまく表示できない」が何を指しているのかが曖昧です。
    https://www.itlab51.com/?p=2912


    > 様々な文字コードが混在しているデータを揃えてListBoxに表示させる方法を教えてください。
    String 型の内部データの文字コードは UTF-16 相当で固定です。

    タブやスペースなどで区切った複数列表示にしたいという事でしょうか?
    その場合は、ListBox 以外のコントロール
    (たとえば ListView の Details モードなど)を使うことを
    検討してみた方が良いと思います。

    あるいは固定幅フォントを用いるようにしたうえで、
    文字幅(いわゆる半角/全角の類)を考慮した文字列を用意するか、
    あるいはオーナードローするとか。
    http://hanatyan.sakura.ne.jp/vb2005/vb2013listbox04.htm
記事No.101955 のレス /過去ログ178より / 関連記事表示
削除チェック/

■101957  Re[1]: ListBoxに表示する文字列を揃える方法
□投稿者/ kiku -(2023/05/19(Fri) 14:31:31)
    No101955 (初心者 さん) に返信
    > VB初心者です。
    >
    > VB2005 .NETでwindowsアプリケーションを作成しています。
    > ファイルデータの中から特定の情報のみを抽出して、左揃えでListBoxに表示させたいです。
    > SHIFT-JISやUNICODE、UTFなどの様々な文字コードが混在しており、上手く左揃えで表示できません。
    >
    > 様々な文字コードが混在しているデータを揃えてListBoxに表示させる方法を教えてください。

    1つのファイルの中身が、文字コードが混在されている状態なのでしょうか?
    その場合、そのファイルをバイナリで読み取ってから、
    ここから、ここまでは、UTF8、
    ここから、ここまでは、シフトJISなどの
    ファイルとしてのルールなどがあり、
    適宜適切な文字コードで取り込んでいるのでしょうか?

    あまり、そんなファイルを扱ったことがないので確認です。
記事No.101955 のレス /過去ログ178より / 関連記事表示
削除チェック/

■101958  Re[2]: ListBoxに表示する文字列を揃える方法
□投稿者/ 初心者 -(2023/05/19(Fri) 15:22:39)
    魔界の仮面弁士、kiku さん返信ありがとうございます。

    説明不足ですみません。
    複数のファイルからデータ(名前や地名、番号など)を読みだしてきています。
    データが英語やハングル、中国語など様々な言語で管理されています。
    例、個人001.dat(英語) 個人002.dat(日本語) 個人003.dat(中国語) ...
    下記サイトを参考に空白埋めで揃えようとしています。
    http://hanatyan.sakura.ne.jp/dotnet/StrCut.htm

    <現状>
    個人001 : aaa abc 25
    個人002 : bbb あああ 75
    個人003 : ccc 哦哦哦 66

    <やりたいこと>
    個人001 : aaa abc 25
    個人002 : bbb あああ 75
    個人003 : ccc 哦哦哦 66
記事No.101955 のレス /過去ログ178より / 関連記事表示
削除チェック/

■101959  Re[3]: ListBoxに表示する文字列を揃える方法
□投稿者/ 魔界の仮面弁士 -(2023/05/19(Fri) 16:36:09)
    2023/05/19(Fri) 16:56:19 編集(投稿者)

    No101958 (初心者 さん) に返信
    > 下記サイトを参考に空白埋めで揃えようとしています。
    > http://hanatyan.sakura.ne.jp/dotnet/StrCut.htm
    それは Shift_JIS の文字集合に収録されている文字のみを対象とした手法です。
    日本語環境を前提としたものであり、他言語環境で通用する手法ではありません。

    たとえば Unicode には「ゼロ幅文字」というものが存在しますが、それには非対応です。
    同じ文字であっても、文章の先頭に来た場合と
    二文字目以降に来た場合で文字幅が異なる言語なんてもありますしね。

    あるいは、
     TextBox1.Text = ChrW(&HD842) & ChrW(&HDFB7) & ChrW(&H91CE) & ChrW(&H5BB6)
     TextBox2.Text = ChrW(&H5409) & ChrW(&H91CE) & ChrW(&H5BB6)
    のような文字列の桁位置合わせにも向かないでしょう。(両者はいずれも漢字 3 文字)

    また、『┠』や『α』といった文字は、日本語向けフォントでは
    全角相当でレンダリングされることが多いですが、他国語対応フォントでは
    半角相当でレンダリングされる可能性があります。


    なので空白でそろえるのではなく、先ほどの回答でも述べたように、
    ListBox を使う代わりに、1 行を複数の列で表示できるコントロール
    (ListView など)に変更するか、あるいはオーナードローなどで
    対処することをお奨めします。
    http://hanatyan.sakura.ne.jp/vb2005/vb2013listview01.htm

    > データが英語やハングル、中国語など様々な言語で管理されています。
    元データの「文字コード」が混在しているわけではないですよね?


    たとえば、文字集合としての Unicode であれば、
    同一の文字コード(UTF-7 とか UTF-8 とか UTF-16LE とか)にて、
    それらの文字種を同時に扱えます。

    厳密にいえば Unicode バージョンによって収録している文字数が異なりますし、
    Unicode 未収録の文字(たとえば日本の戸籍統一文字の一部など)もあるので、
    複数の文字コードを併用して管理することが無いとは言えませんけれどね…。

    -- 以下蛇足 --
    たとえば韓国語の場合、ハングル自体は 24 種(子音14個+母音10個)ですが、
    それらの組み合わせで一つの文字を表すため、文字種そのものは 11,172個あります。
    しかし日常で使う文字は3〜4千字程度なので、韓国系文字コードでは
    よく使われるハングルしか収録されていません。

    韓国の Wansung (KS X 1001:2002) に収録されている文字数は
    8227文字(ハングル2350字、漢字4888字、その他989)です。
    これには 平仮名(83文字)や片仮名(86文字)なども含まれています。


    中文漢字向けの物で見てみると、
    GB 18030-2022 で 87,887文字
    GB 18030-2005 で 70,244文字
    という収録状況です。

    ちなみに VB6 当時の Unicode は UCS-2 相当の符号化を想定しており、
    最大でも基本多言語面の 65,536 文字種しか保持できませんでした。

    現在の VB ではサロゲートペアや UTF-8 をサポートしたので、
    Unicode の基本多言語面外の文字を扱えるようになっています。
    (絵文字サポートなどは、WPF と WinForm で状況が異なるのですけれど)

    Unicode 2.0 で 38,950文字を収録
    Unicode 3.2 で 95,221文字を収録(JIS X 0213 に正式対応)
    Unicode 15.0 で 149,186文字を収録
記事No.101955 のレス /過去ログ178より / 関連記事表示
削除チェック/

■101960  Re[4]: ListBoxに表示する文字列を揃える方法
□投稿者/ 魔界の仮面弁士 -(2023/05/19(Fri) 18:12:58)
    No101959 (魔界の仮面弁士) に追記
    > なので空白でそろえるのではなく、先ほどの回答でも述べたように、
    > ListBox を使う代わりに、1 行を複数の列で表示できるコントロール
    > (ListView など)に変更するか、あるいはオーナードローなどで
    > 対処することをお奨めします。
    > http://hanatyan.sakura.ne.jp/vb2005/vb2013listview01.htm

    ListBox の代わりに ListView を使ってみるサンプル。


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
      ' このあたりはデザイン時に指定しておけばよい
      ListView1.View = View.Details
      ListView1.FullRowSelect = True
      ListView1.GridLines = False
      ListView1.Columns.Add("列1")
      ListView1.Columns.Add("列2")
      ListView1.Columns.Add("列3")
      ListView1.Columns.Add("列4").TextAlign = HorizontalAlignment.Right
      ListView1.HeaderStyle = ColumnHeaderStyle.Nonclickable
      'ListView1.HeaderStyle = ColumnHeaderStyle.None '列ヘッダが不要な場合


      'データ登録
      ListView1.Items.Add("個人001").SubItems.AddRange(New String() {"aaa", "abc", "25"})
      ListView1.Items.Add("個人002").SubItems.AddRange(New String() {"bbb", "あああ", "75"})
      ListView1.Items.Add("個人003").SubItems.AddRange(New String() {"ccc", "哦哦哦", "66"})
    End Sub
記事No.101955 のレス /過去ログ178より / 関連記事表示
削除チェック/

■101961  Re[3]: ListBoxに表示する文字列を揃える方法
□投稿者/ KOZ -(2023/05/19(Fri) 19:26:13)
    2023/05/19(Fri) 23:37:30 編集(投稿者)

    No101958 (初心者 さん) に返信
    > <やりたいこと>
    > 個人001 : aaa abc 25
    > 個人002 : bbb あああ 75
    > 個人003 : ccc 哦哦哦 66

    ゼロ幅スペースやサロゲートペアなどを考えると幅を求めるのは結構やっかいです。
    面倒なことは知ってる人にやらせてみます。(つまり GDI に聞く。)
    描画領域には余白があるので最初に半角2文字の幅から半角1文字の幅を引いて
    1文字あたりの幅を求めます。残りが余白になるのでそれをもとに判定していきます、

    Imports System.Globalization

    Public Class Form1

    Private _Graphics As Graphics = Graphics.FromHwnd(IntPtr.Zero)
    Private _FixedFont As New Font("MS ゴシック", 9.75!, FontStyle.Regular)
    Private _HalfCharWidth As Integer
    Private _Padding As Integer

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim twoCharWidth As Integer = GetDrawWidth("AA")
    Dim oneCharWidth As Integer = GetDrawWidth("A")
    _HalfCharWidth = twoCharWidth - oneCharWidth
    _Padding = twoCharWidth - _HalfCharWidth
    ListBox1.Font = _FixedFont
    ListBox1.Items.Clear()
    ListBox1.Items.Add(EditItem("個人001", "aaa", "abc", "25"))
    ListBox1.Items.Add(EditItem("個人002", "bbb", "あああ", "75"))
    ListBox1.Items.Add(EditItem("個人003", "ccc", "哦哦哦", "66"))
    End Sub

    Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
    _Graphics.Dispose()
    _Graphics = Nothing
    _FixedFont.Dispose()
    _FixedFont = Nothing
    End Sub

    Private Function EditItem(item1 As String, item2 As String, item3 As String, item4 As String) As String
    Return RightPad(item1, 8) & ": " & RightPad(item2, 7) & RightPad(item3, 13) & item4
    End Function

    Private Function GetDrawWidth(text As String) As Integer
    Return TextRenderer.MeasureText(_Graphics, text, _FixedFont).Width
    End Function

    Private Function RightPad(text As String, nLength As Integer) As String
    Dim drawWidth As Integer = GetDrawWidth(text)
    Dim needWidth As Integer = nLength * _HalfCharWidth + _Padding '必要な長さ
    If drawWidth > needWidth Then
    '必要な長さになるまで末尾を削る
    Dim info As New StringInfo(text)
    Dim length As Integer = info.LengthInTextElements - 1
    While drawWidth > needWidth
    text = info.SubstringByTextElements(0, length)
    drawWidth = GetDrawWidth(text)
    length -= 1
    End While
    End If
    Return text & New String(" "c, (needWidth - drawWidth) \ _HalfCharWidth)
    End Function

    End Class
記事No.101955 のレス /過去ログ178より / 関連記事表示
削除チェック/

■101963  Re[3]: ListBoxに表示する文字列を揃える方法
□投稿者/ radian -(2023/05/22(Mon) 10:09:46)
    2023/05/22(Mon) 11:33:21 編集(投稿者)

    No101958 (初心者 さん) に返信
    > データが英語やハングル、中国語など様々な言語で管理されています。
    > 例、個人001.dat(英語) 個人002.dat(日本語) 個人003.dat(中国語) ...
    > 下記サイトを参考に空白埋めで揃えようとしています。
    > http://hanatyan.sakura.ne.jp/dotnet/StrCut.htm
    >
    > <現状>
    > 個人001 : aaa abc 25
    > 個人002 : bbb あああ 75
    > 個人003 : ccc 哦哦哦 66
    >
    > <やりたいこと>
    > 個人001 : aaa abc 25
    > 個人002 : bbb あああ 75
    > 個人003 : ccc 哦哦哦 66

    空白埋めで揃えるというアプローチがそもそも間違っているので、
    表っぽくしたいならDataGridViewか、弁士さんの別解にあるListViewでも使った方がいいと思います。


    Protected Overrides Sub OnLoad(e As EventArgs)
    MyBase.OnLoad(e)

    'DataGridView設定(ListBox風)
    DataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect
    'DataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.None ←セル境界線が要らないなら設定
    DataGridView1.ColumnHeadersVisible = False
    DataGridView1.RowHeadersVisible = False
    DataGridView1.AllowUserToResizeColumns = False
    DataGridView1.AllowUserToResizeRows = False
    DataGridView1.AllowUserToAddRows = False
    DataGridView1.ReadOnly = True
    DataGridView1.MultiSelect = False '複数行選択したいならTrue

    'DataGridView行を作る
    DataGridView1.Columns.AddRange({
    New DataGridViewTextBoxColumn() With {.DataPropertyName = "Col1", .Width = 50},
    New DataGridViewTextBoxColumn() With {.DataPropertyName = "Col2", .Width = 50},
    New DataGridViewTextBoxColumn() With {.DataPropertyName = "Col3", .Width = 50},
    New DataGridViewTextBoxColumn() With {.DataPropertyName = "Col4", .Width = 50}
    })

    'DataTableを作成し、DataGridViewに設定
    Dim dt As New DataTable
    dt.Columns.Add("Col1")
    dt.Columns.Add("Col2")
    dt.Columns.Add("Col3")
    dt.Columns.Add("Col4")
    dt.Rows.Add({"個人001", "aaa", "abc", "25"})
    dt.Rows.Add({"個人002", "bbb", "あああ", "75"})
    dt.Rows.Add({"個人003", "ccc", "哦哦哦", "66"})
    DataGridView1.DataSource = dt

    End Sub
記事No.101955 のレス /過去ログ178より / 関連記事表示
削除チェック/

■101977  Re[4]: ListBoxに表示する文字列を揃える方法
□投稿者/ 初心者 -(2023/05/23(Tue) 14:00:48)
    No101963 (radian さん) に返信
    > 2023/05/22(Mon) 11:33:21 編集(投稿者)
    >
    > ■No101958 (初心者 さん) に返信
    >>データが英語やハングル、中国語など様々な言語で管理されています。
    >>例、個人001.dat(英語) 個人002.dat(日本語) 個人003.dat(中国語) ...
    >>下記サイトを参考に空白埋めで揃えようとしています。
    >>http://hanatyan.sakura.ne.jp/dotnet/StrCut.htm
    >>
    >><現状>
    >>個人001 : aaa abc 25
    >>個人002 : bbb あああ 75
    >>個人003 : ccc 哦哦哦 66
    >>
    >><やりたいこと>
    >>個人001 : aaa abc 25
    >>個人002 : bbb あああ 75
    >>個人003 : ccc 哦哦哦 66
    >
    > 空白埋めで揃えるというアプローチがそもそも間違っているので、
    > 表っぽくしたいならDataGridViewか、弁士さんの別解にあるListViewでも使った方がいいと思います。
    >
    >
    > Protected Overrides Sub OnLoad(e As EventArgs)
    > MyBase.OnLoad(e)
    >
    > 'DataGridView設定(ListBox風)
    > DataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect
    > 'DataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.None ←セル境界線が要らないなら設定
    > DataGridView1.ColumnHeadersVisible = False
    > DataGridView1.RowHeadersVisible = False
    > DataGridView1.AllowUserToResizeColumns = False
    > DataGridView1.AllowUserToResizeRows = False
    > DataGridView1.AllowUserToAddRows = False
    > DataGridView1.ReadOnly = True
    > DataGridView1.MultiSelect = False '複数行選択したいならTrue
    >
    > 'DataGridView行を作る
    > DataGridView1.Columns.AddRange({
    > New DataGridViewTextBoxColumn() With {.DataPropertyName = "Col1", .Width = 50},
    > New DataGridViewTextBoxColumn() With {.DataPropertyName = "Col2", .Width = 50},
    > New DataGridViewTextBoxColumn() With {.DataPropertyName = "Col3", .Width = 50},
    > New DataGridViewTextBoxColumn() With {.DataPropertyName = "Col4", .Width = 50}
    > })
    >
    > 'DataTableを作成し、DataGridViewに設定
    > Dim dt As New DataTable
    > dt.Columns.Add("Col1")
    > dt.Columns.Add("Col2")
    > dt.Columns.Add("Col3")
    > dt.Columns.Add("Col4")
    > dt.Rows.Add({"個人001", "aaa", "abc", "25"})
    > dt.Rows.Add({"個人002", "bbb", "あああ", "75"})
    > dt.Rows.Add({"個人003", "ccc", "哦哦哦", "66"})
    > DataGridView1.DataSource = dt
    >
    > End Sub
    >
記事No.101955 のレス / END /過去ログ178より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -