連載

Windows業務アプリケーション開発 Q&A #2

グレープシティ株式会社 八巻 雄哉
2006/07/12

本記事は、業務アプリケーション向けコンポーネントのベンダであるグレープシティのテクニカル・サポート担当に対して、実際にプログラマーから問い合わせがあった質問を取り上げて解説しています。

データグリッドでうまく並べ替えできない

 Windowsフォームのグリッド・コントロールにおいて、1行目の値が「0-02」、2行目の値が「001」の列に対して昇順に並べ替えを行うと、1行目が「001」になってしまいます。文字コード上では、「-」は「0」よりも小さいため、「0-02」が1行目となるのが正しいように思いますが、これはなぜでしょうか? これは業務アプリケーションで使用しているグレープシティさんのSPREAD 7.0Jでの話ですが、.NET標準のデータグリッド・コントロールでも同じ動作となるようです。

 並べ替え(ソート)の結果このような順番になるのは、ハイフン(-)およびアポストロフィ(')は無視するというWindowsの並べ替えの仕様に基づくものです。

 例えば、Visual Basic 6.0(以下、VB 6)のListBoxコントロールにおけるSortedプロパティを使用した並べ替え、Visual Studio 2005(以下、VS 2005)のDataGridViewコントロールにデフォルトで実装されている列の並べ替え、いずれの場合でも同様の動作となります。

 また、Excel 2003などのアプリケーションにおいても同様で、ハイフンおよびアポストロフィは無視されます*(ただし、Microsoft Officeの古いバージョンであるWord 7.0などでは、並べ替え時にハイフンやアポストロフィは無視されません)。

* 参考:Microsoftサポートオンライン:Excelで並べ替えを実行したときハイフンとアポストロフィがアルファベットの後ろに配置される

 さて、VB 6ではコントロールに組み込まれた並べ替えの処理をカスタマイズするなんてことは当然ながらできませんでした。ところが本格的なオブジェクト指向となり、豊富なクラス・ライブラリを得た.NETのVisual Basicではそれが可能となっています。

 ここでは、VS 2005標準のDataGridViewコントロールを使用した場合の最もシンプルな例を紹介したいと思います。

 まず、DataGridViewコントロールにおける通常の並べ替え動作を確認しておきましょう。VS 2005でWindowsアプリケーションのプロジェクトを新規作成し、フォームにDataGridViewコントロールを配置して下記のコードを記述してください。ここでは言語としてVisual Basicを使用します。

Public Class Form1

  ' フォームのLoadイベント・ハンドラ
  Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load

    ' DataGridViewに表示される列の数を設定します。
    DataGridView1.ColumnCount = 1

    ' DataGridViewの列の各プロパティを設定します。
    DataGridView1.Columns(0).Name = "id"
    DataGridView1.Columns("id").HeaderText = "番号"

    ' DataGridViewにデータを追加します。
    DataGridView1.Rows.Add("003")
    DataGridView1.Rows.Add("0-02")
    DataGridView1.Rows.Add("001")
  End Sub
End Class
リスト1 1列3行の単純なDataGrideViewコントロールを表示するコード

 このアプリケーションを実行し、列ヘッダ部分をクリックして行の並べ替えを行うと下図のような結果となります。

列ヘッダ(「番号」の部分)をクリックして並べ替えた結果

 ハイフンが無視されて並べ替えられているのが確認できますね。

 では次に、下記のコードを先ほど記述したForm1クラスの中に追加してください。

Private Sub DataGridView1_ColumnHeaderMouseClick(ByVal sender As Object, ByVal e As DataGridViewCellMouseEventArgs) Handles DataGridView1.ColumnHeaderMouseClick
  ' StringSortで並べ替えを行います。
  Dim myComp = New MyStringComparer()
  DataGridView1.Sort(myComp)
End Sub

' IComparerインターフェイスを実装したクラス
Private Class MyStringComparer
  Implements IComparer

  ' "ja-JP"のカルチャーに合った文字列比較を行います。
  Private myComp As CompareInfo = CompareInfo.GetCompareInfo("ja-JP")

  ' 文字列の比較時に、ハイフン、アポストロフィ、および
  ' そのほかの英数字以外の記号が英数字よりも前になる
  ' 文字列並べ替えアルゴリズムを使用します。
  Private myOptions As CompareOptions = CompareOptions.StringSort

  ' 比較オプションとしてStringSortを使用して文字列を比較します。
  Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare

    Dim DataGridViewRow1 As DataGridViewRow _
        = CType(x, DataGridViewRow)
    Dim DataGridViewRow2 As DataGridViewRow _
        = CType(y, DataGridViewRow)

    Dim CompareResult = myComp.Compare( _
      DataGridViewRow1.Cells(0).Value.ToString(), _
      DataGridViewRow2.Cells(0).Value.ToString(), _
      myOptions)

    Return CompareResult
  End Function
End Class
リスト2 ハイフンやアポストロフィを無視しない並べ替えを実現するコード例

 また、Form1.vbの1行目には下記の行を追加してください。

Imports System.Globalization

.NET TIPS:配列を独自の順序でソート(並べ替え)するには?
.NET TIPS:自作クラスによる配列をソート(並べ替え)するには?

 DataGridViewコントロールのSortメソッドには、IComparerインターフェイスの実装を使用して並べ替えを行うオーバーロードされたバージョンが用意されています。これを使用するために、リスト2ではIComparerインターフェイスを実装したMyStringComparerというクラスを作成しています。

 このMyStringComparerクラスの中で、CompareInfoクラス(System.Globalization名前空間)のCompareメソッドを使用し、CompareOptions列挙体のStringSortを指定することで、ハイフンやアポストロフィを無視しない並べ替えを実現することができます。

 再度アプリケーションを実行すると、下図のようにハイフンを含めた並べ替え処理が行われることを確認できるはずです。

リスト2の追加後に列ヘッダをクリックして並べ替えした結果

 ここではDataGridViewコントロールを使用しましたが、グレープシティの表計算コンポーネントである「SPREAD for .NET」や、グリッド・コンポーネントである「FlexGrid for .NET」でも、同様の方法を用いて並べ替え処理をカスタマイズすることが可能となっています。

 なお、DataSourceプロパティを設定してグリッド・コントロールを外部データソースにバインドしている場合、この方法は使用できません。その場合、データソースによって提供される並べ替え操作を使用する必要があるため、もう少し複雑な処理が必要となります。

 

VS.NET 2003でWebアプリ開発時にエラーが発生してしまう

 Visual Studio .NET 2003を使ってWebアプリケーションを開発しているのですが、デバッグ実行を行っていると不定期に「構成にエラーがあります。」というエラーが発生します。これはどのようなことが原因で発生しているのでしょうか?

 Visual Studio .NET 2002および2003を使用してWebアプリケーションを開発している場合、デバッグ実行をすると不定期に下記のようなエラーが表示されることがあります。

'/*****' アプリケーションでサーバー エラーが発生しました。
構成にエラーがあります。
説明 : この要求を処理するために必要な構成ファイルの処理中にエラーが発生しました。次のエラーの詳細を確認し、構成ファイルに変更を加えてください。

解析エラー メッセージ: アクセスが拒否されました : '*****'.
Visual Studio .NET 2002および2003で不定期に発生するエラー
Webアプリケーションをデバッグ実行していると、このようなエラーが発生する場合がある。

 「解析エラー・メッセージ」の内容が「アクセスが拒否されました」となっており、構成ファイル(Web.Configファイル)に変更を加えていないにもかかわらず、このエラーが発生したりしなかったりする場合、Windowsのインデックス・サービスがこのエラーを引き起こしている可能性が高いです*

* 参考:[PRB] インデックス サービスの実行中にコードに変更を加えるとアクセス拒否エラーが発生する

 インデックス・サービスを実行している場合、ASP.NETのテンポラリ・ディレクトリ(通常は「C:\WINDOWS\Microsoft.NET\Framework\<バージョン番号>\Temporary ASP.NET Files」)の再スキャンが行われ、数分間ロック状態になります。これによりASP.NETのワーカー・プロセスで特定のDLLを読み込めなくなり、エラーとなります。

 よって、インデックス・サービスを無効にするか、もしくはインデックス・サービスのスキャン対象からASP.NETのテンポラリ・ディレクトリを除外することで、この問題を解決することができます。

【インデックス・サービスを無効にする方法】

  • Windowsの管理ツールの中の「サービス」を開いて、「Indexing Service」を無効に設定します。

【インデックス・サービスのスキャン対象から除外する方法】

  1. Windowsの管理ツールの中の「コンピュータの管理」を開いて、画面左側のツリーで[サービスとアプリケーション]−[インデックス サービス]−[System]の順に展開します。
  2. [ディレクトリ]の項目を右クリックし、[新規作成]−[ディレクトリ]をクリックします。
  3. [ディレクトリの追加]ダイアログにおいて、[パス]にASP.NETのテンポラリ・ディレクトリを指定し、[インデックスに含めますか?]は[いいえ]を設定します。
  4. 「Indexing Service」のサービスを再起動します。

 なお、インデックス・サービス以外にも、ウイルス対策ソフトによるファイル・スキャンなどによって同様の現象が発生することがあるようです。End of Article


八巻 雄哉(やまき ゆうや)
グレープシティ株式会社 テクニカルエバンジェリスト

2003年グレープシティ入社。PowerToolsシリーズのテクニカル・サポートを担当する傍ら、製品開発やマーケティングにも従事。現在は.NETとPowerToolsシリーズ普及のため、エバンジェリストとして活動中。初めて触れたプログラミング言語は「MSX-BASIC」なので、やっぱりマイクロソフト製。http://d.hatena.ne.jp/Yamaki/にてBlogを公開中。


インデックス・ページヘ  「Windows業務アプリケーション開発 Q&A」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH