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

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

C# と VB.NET の入門サイト

Re[8]: Selectを使ってエラーが出た時の原因


(過去ログ 144 を表示中)

[トピック内 11 記事 (1 - 11 表示)]  << 0 >>

■84156 / inTopicNo.1)  Selectを使ってエラーが出た時の原因
  
□投稿者/ 夜叉丸 (53回)-(2017/05/24(Wed) 11:22:52)

分類:[.NET 全般] 

お世話になります。

 arryrow = dttemp.Select("", "DNAME").ToArray();

このコード:DNAME 順で並び変えたいだけなのですが
実行するパソコンでエラーが発生するものと発生しないものがあります。
原因がなんなのかわからなくて困っているのですがわかる方いませんでしょうか?

DataRow[] arryrow = arryrow = dttemp.Select("", "DNAME").ToArray();

↓↓↓↓↓↓↓↓↓↓

DataRow[] arryrow = null;
try
{
 arryrow = dttemp.Select("", "DNAME").ToArray();
}
catch(Exception ex)
{
 WriteFile("---------- Select ----------" + ex.Message);
 return;
}

public void WriteFile(string text)
{
 string filePath = @System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\debug.txt";
 StreamWriter sw = new StreamWriter(filePath, true, Encoding.GetEncoding("shift_jis"));
 sw.Write(text + "\r\n");
 sw.Close();
}

これで表示されるエラーメッセージは
インデックスエラーでした

直前の DataTable dttemp の内容は OKなPCもNGなPCも 同じでした

List<string> strlst = new List<string>();
for(int icnum = 0; icnum < dttemp.Columns.Count; icnum++) strlst.Add(dttemp.Columns[icnum].ColumnName);
WriteFile(string.Join(" ", strlst));
for(int irnum = 0; irnum < dttemp.Rows.Count; irnum++)
{
 strlst.Clear();
 for(int icnum = 0; icnum < dttemp.Rows[irnum].Table.Columns.Count; icnum++)
  strlst.Add(dttemp.Rows[irnum][icnum].ToString());
 WriteFile(string.Join(" ", strlst));
}

引用返信 編集キー/
■84186 / inTopicNo.2)  Re[1]: Selectを使ってエラーが出た時の原因
□投稿者/ アプレヴー (1回)-(2017/05/26(Fri) 12:40:35)
例外の内容は何ですか?
ターゲットフレームワークは何ですか?
引用返信 編集キー/
■84187 / inTopicNo.3)  Re[1]: Selectを使ってエラーが出た時の原因
□投稿者/ 魔界の仮面弁士 (1291回)-(2017/05/26(Fri) 15:12:40)
No84156 (夜叉丸 さん) に返信
> これで表示されるエラーメッセージは
> インデックスエラーでした
エラーメッセージは『列 DNAME が見つかりません。』でしょうか。
あるいはそれ以外のメッセージでしょうか?



> 原因がなんなのかわからなくて困っているのですがわかる方いませんでしょうか?
dttemp.DataSet は null でしょうか。非 null でしょうか。
非 null の場合、リレーションに差異が無いかも確認してみてください。

また、
 dttemp.Select("", "DNAME")
のかわりに
 dttemp.Select("", "[DNAME]")
とした場合、両環境での結果は変化しますか?

とりあえず手元の環境では、再現可能な DataTable を用意できませんでした。
CLR2 でも CLR4 でも変わらず…。

var dttemp = new DataTable("Table1");
dttemp.CaseSensitive = false;
dttemp.Columns.Add("DNAME", typeof(string));
dttemp.Rows.Add("TEST");
dttemp.Rows.Add(DBNull.Value);
dttemp.Rows.Add(default(string));
dttemp.Rows.Add(String.Empty);
dttemp.Rows.Add(Type.Missing);
dttemp.AcceptChanges();
dttemp.Rows[0].Delete();



> このコード:DNAME 順で並び変えたいだけなのですが
> 実行するパソコンでエラーが発生するものと発生しないものがあります。
dttemp.Columns の列名では、「大文字・小文字・全角・半角・ひらがな・カタカナ」が区別されます。
しかし利用時(たとえば Select メソッドでの問い合わせ時)では、それらが同一視されることになります。

たとえば Select メソッド等に列名が指定された場合、
まずは大文字小文字などを区別する形で検索され、
該当するものがあればそれが使われることになります。

該当列が見つからない場合は、さらに大文字小文字等を同一視した再検索が行われます。
再検索後、該当する列名が 1 つだけ見つかればそれが使われますが、
複数の列にマッチした場合は ArgumentException の例外になり、
何も見つからなければ IndexOutOfRangeException の例外になります。怪しいのはこのパターンですが、
動作する環境と動作しない環境があるという点が謎ですね。


> 直前の DataTable dttemp の内容は OKなPCもNGなPCも 同じでした
過去ログ No81962 で紹介した BID トレースを比較してみるのはどうでしょう。
役に立つかは不明ですが(溺藁

http://msdn.microsoft.com/ja-jp/library/ms971550.aspx
https://blogs.msdn.microsoft.com/jpsql/2011/11/07/howto-bid/



--- 以下蛇足 ---

>  arryrow = dttemp.Select("", "DNAME").ToArray();

dttemp は DataTable 型ですよね。
であれば、ToArray() 拡張メソッドの呼びだしは冗長でしょう。

DataTable の Select メソッドの戻り値は DataRow[] 型なので、
ToArray を呼び出す必要はないでしょう。


>  string filePath = @System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\debug.txt";

上記のコードで @ は不要(というか無意味)に思えます。

また、using System; や using System.IO; も行われているようですので、
 string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "debug.txt");
の方が良いのではないでしょうか。


使おうとすれば、他の箇所にも @ をちりばめて
 string @filePath = global::@System.@Environment.@GetFolderPath(global::@System.@Environment.@SpecialFolder.@DesktopDirectory) + @"\debug.txt";
などと書けなくは無いですが。
引用返信 編集キー/
■84191 / inTopicNo.4)  Re[2]: Selectを使ってエラーが出た時の原因
□投稿者/ 夜叉丸 (58回)-(2017/05/29(Mon) 18:00:47)
2017/05/29(Mon) 18:34:10 編集(投稿者)

遅くなってすみません。

エラーメッセージは
【インデックスが配列の境界外です。】
と、表示されます。

dttemp の中身は正常に動作するPCも動作しないPCも
同じ内容になっているので、PCの環境によるものだと思うのですが。

違うのでしょうか?


> DataTable の Select メソッドの戻り値は DataRow[] 型なので、
> ToArray を呼び出す必要はないでしょう。
ToArray() をつけないと var というちょっと意味不明の型になるのかと思っていました。
なので、今まで意味が分かる DataRow[] にするのに ToArray() をずっとつけてました。


>>  string filePath = @System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\debug.txt";
> 上記のコードで @ は不要(というか無意味)に思えます

どこかのサイトからひっぱて来たときに@がついていたのでそのまま使用しました。


> ターゲットフレームワークは何ですか?
フレームワークですが

動作しない方は、
Microsoft .NET Framework 4 Client Profile
Microsoft .NET Framework 4 Client Profile Language Pack - 日本語

動作するほうは、
Microsoft .NET Framework 4.6.1
Microsoft .NET Framework 4 Client Profile Lang...
Microsoft .NET Framework 4 Extended Languag...


もう一台はノートになりますが、
V4.0 Client でしたが、動作しました。



引用返信 編集キー/
■84220 / inTopicNo.5)  Re[3]: Selectを使ってエラーが出た時の原因
□投稿者/ 夜叉丸 (60回)-(2017/06/01(Thu) 08:28:01)
パソコンの環境や性能の違いによって
DataTable の構成とか、処理がかわるということはあるんでしょうか?
引用返信 編集キー/
■84222 / inTopicNo.6)  Re[4]: Selectを使ってエラーが出た時の原因
□投稿者/ 魔界の仮面弁士 (1302回)-(2017/06/01(Thu) 10:59:56)
No84220 (夜叉丸 さん) に返信
> パソコンの環境や性能の違いによって
> DataTable の構成とか、処理がかわるということはあるんでしょうか?

無いとは言えませんが、IndexOutOfRangeException になるパターンは見たことがありません。
現象を再現可能な DataTable が手に入れば追加検証もできるのですが。

過去の事例では、CLR1 → CLR2 への切り替わりで、DataRow に対する
非互換的な改修があったりもしましたが、今回は開発も実行環境も CLR4 ですよね?



No84191 (夜叉丸 さん) に返信
> dttemp の中身は正常に動作するPCも動作しないPCも
> 同じ内容になっているので、PCの環境によるものだと思うのですが。

それぞれの環境で下記を実行して、dttemp の内容をローカルファイルに保存してみてください。

string folder = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
if (dttemp.DataSet != null)
{
  string file = System.IO.Path.Combine(folder, "DataSet.XML");
  dttemp.DataSet.WriteXml(file, XmlWriteMode.WriteSchema);
}
else
{
  string file = System.IO.Path.Combine(folder, "DataTable.XML");
  dttemp.WriteXml(file, XmlWriteMode.WriteSchema);
}


その上で、保存したファイルを他方の PC に持ち込んで
  var dsTest = new DataSet();
  dsTest.ReadXml(file);
あるいは
  var dsTable = new DataTable();
  dsTable.ReadXml(file);
として再現し、Select メソッドが例外を発するか確認してみてください。



>> ターゲットフレームワークは何ですか?
> フレームワークですが

ターゲット フレームワークと言うのは、開発環境でプロジェクトのプロパティを開いたときに
[アプリケーション]タブの『対象のフレームワーク』に表示されるものの事です。



--- 以下、本題からは外れますが ---

>> DataTable の Select メソッドの戻り値は DataRow[] 型なので、
>> ToArray を呼び出す必要はないでしょう。
> ToArray() をつけないと var というちょっと意味不明の型になるのかと思っていました。

匿名型が渡された場合は「意味不明な型」に見えるかもしれませんが、
少なくとも Select メソッドの戻り値はそうではありません。単なる DataRow 配列です。



> >>  string filePath = @System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\debug.txt";
>>上記のコードで @ は不要(というか無意味)に思えます
> どこかのサイトからひっぱて来たときに@がついていたのでそのまま使用しました。

@では無く@ですよね。どのサイトだったか覚えておられますか?
System.Environment.GetFolderPath の冒頭に付与するメリットが見出せません…。


文法的には、今回の @System のように名前空間・型名・メンバー名・変数名の先頭に
@ を付与することができますが、それは本来、「int @for = 0;」などのように、
エスケープしないと表現できないケースで使われるものです。


先頭に @ をつけるのは、多くの場合『\ を含む文字列』を簡単に記述するためです。
このケースと勘違いしていたという事は無いでしょうか。

string filePath1 = "C:\\folder1\\folder2\\sample.txt";
string filePath2 = @"C:\folder1\folder2\sample.txt";

string folder1 = "\\\\localhost\\C$\\Program Files\";
string folder2 = @"\\localhost\C$\Program Files\";

var re1 = new Regex("\\w+-\\w+", RegexOptions.Multiline);
var re2 = new Regex(@"\w+-\w+", RegexOptions.Multiline);


あるいは、改行を含む複数行の文字列を記載する目的でも利用されます。

var sql = "
SELECT COL1, COL2 FROM Table1
WHERE COL1 < 100
ORDER BY COL1 DESC, COL2
";
引用返信 編集キー/
■84301 / inTopicNo.7)  Re[5]: Selectを使ってエラーが出た時の原因
□投稿者/ 夜叉丸 (61回)-(2017/06/13(Tue) 15:11:48)
No84222 (魔界の仮面弁士 さん) に返信

> 過去の事例では、CLR1 → CLR2 への切り替わりで、DataRow に対する
> 非互換的な改修があったりもしましたが、今回は開発も実行環境も CLR4 ですよね?

すみません。CLR1、CLR2というのは何のことでしょうか?

> それぞれの環境で下記を実行して、dttemp の内容をローカルファイルに保存してみてください。
>
> string folder = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
> if (dttemp.DataSet != null)
> {
>   string file = System.IO.Path.Combine(folder, "DataSet.XML");
>   dttemp.DataSet.WriteXml(file, XmlWriteMode.WriteSchema);
> }
> else
> {
>   string file = System.IO.Path.Combine(folder, "DataTable.XML");
>   dttemp.WriteXml(file, XmlWriteMode.WriteSchema);
> }
>

SELECT に行く前にこのコードで
DataTable をシリアル化できません。DataTable の名前が設定されていません。
というエラーになりました。


PCのHDDが壊れて返答が遅くなりました。
どうもすみませんでした。
引用返信 編集キー/
■84302 / inTopicNo.8)  Re[6]: Selectを使ってエラーが出た時の原因
□投稿者/ 魔界の仮面弁士 (1320回)-(2017/06/13(Tue) 15:42:17)
2017/06/13(Tue) 15:42:51 編集(投稿者)

No84301 (夜叉丸 さん) に返信
> すみません。CLR1、CLR2というのは何のことでしょうか?

CLR は「共通言語ランタイム」の略です。1 とか 2 はバージョンのこと。

1.0 → .NET Framework 1.0
1.1 → .NET Framework 1.1
2.0 → .NET Framework 2.0/3.0/3.5
4.0 → .NET Framework 4/4.5/4.5.1/4.5.2/4.6/4.6.1/4.6.2/4.7

https://blogs.msdn.microsoft.com/jpvsblog/2015/04/06/net-framework-3/
http://www.atmarkit.co.jp/ait/articles/1211/16/news093.html


> SELECT に行く前にこのコードで
> DataTable をシリアル化できません。DataTable の名前が設定されていません。
> というエラーになりました。

dttemp.TableName が空だとシリアライズできないので、
インスタンス生成部を
 // DataTable dttemp = new DataTable();
 DataTable dttemp = new DataTable("YourTableName");
に変更するか、もしくは WriteXml する直前に
 dttemp.TableName = "YourTableName";
などとしてみてください。

引用返信 編集キー/
■84303 / inTopicNo.9)  Re[6]: Selectを使ってエラーが出た時の原因
□投稿者/ PANG2 (178回)-(2017/06/13(Tue) 15:42:24)
まずは、
> ターゲットフレームワークは何ですか?
の質問に答えましょう。

> 動作しない方は、
> Microsoft .NET Framework 4 Client Profile
> Microsoft .NET Framework 4 Client Profile Language Pack - 日本語

開発環境と実行環境で、 .NET Framework のバージョンが異なるのでは?


---
.NET Framework のバージョンおよび依存関係
https://msdn.microsoft.com/ja-jp/library/bb822049%28v=vs.110%29.aspx

.NET Framework 4.0 と 4.5 は CLR のバージョンが異なる
http://fnya.cocolog-nifty.com/blog/2012/09/net-framework-4.html
引用返信 編集キー/
■84308 / inTopicNo.10)  Re[7]: Selectを使ってエラーが出た時の原因
□投稿者/ 夜叉丸 (62回)-(2017/06/13(Tue) 18:38:49)
2017/06/13(Tue) 18:52:32 編集(投稿者)

ターゲットフレームは4です。

ターゲットフレームワーク [.Net Framework4]
プラットフォームターゲット [x86]

で作成しています。


DataTable.XMLの中身は以下のようになっています。

==================================================

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="DISTINCT" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="DISTINCT">
<xs:complexType>
<xs:sequence>
<xs:element name="NAME" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//DISTINCT" />
<xs:field xpath="NAME" />
</xs:unique>
</xs:element>
</xs:schema>
<DISTINCT>
<NAME>CG</NAME>
</DISTINCT>
<DISTINCT>
<NAME>IR</NAME>
</DISTINCT>
<DISTINCT>
<NAME>RY</NAME>
</DISTINCT>
<DISTINCT>
<NAME>SR</NAME>
</DISTINCT>
<DISTINCT>
<NAME>VR</NAME>
</DISTINCT>
<DISTINCT>
<NAME>GN</NAME>
</DISTINCT>
<DISTINCT>
<NAME>F2</NAME>
</DISTINCT>
<DISTINCT>
<NAME>GI</NAME>
</DISTINCT>
<DISTINCT>
<NAME>CJ</NAME>
</DISTINCT>
<DISTINCT>
<NAME>MX</NAME>
</DISTINCT>
<DISTINCT>
<NAME>C2</NAME>
</DISTINCT>
</NewDataSet>

==================================================

プログラムの中身は以下になります。

rtb は RichTextBox です。

==================================================
namespace test
{
 public partial class Form1 : Form
 {
  public Form1()
  {
   InitializeComponent();
  }

  private void SetDataRow(DataTable dt, int dy, int id, string name, int count)
  {
   DataRow drw = dt.NewRow();
   drw["DY"] = dy;
   drw["ID"] = id;
   drw["NAME"] = name;
   drw["COUNT"] = count;
   dt.Rows.Add(drw);
  }

  public static DataTable Distinct(DataTable dtsource, params string[] colnames)
  {
#if false
   DataTable dtdest = dtsource.Clone();
#else
   DataTable dtdest = new DataTable("DISTINCT");
   for(int icnum = 0; icnum < dtsource.Columns.Count; icnum++)
   {
    dtdest.Columns.Add(dtsource.Columns[icnum].ColumnName, dtsource.Columns[icnum].DataType);
   }
#endif
   DataColumn[] dc = new DataColumn[colnames.Length];
   for (int icolnamenum = 0; icolnamenum < colnames.Length; icolnamenum++) dc[icolnamenum] = dtdest.Columns[colnames[icolnamenum]];
   dtdest.PrimaryKey = dc;

   foreach (DataRow drsource in dtsource.Rows)
   {
    object[] keys = new object[colnames.Length];
    for (int ikeynum = 0; ikeynum < colnames.Length; ikeynum++) keys[ikeynum] = drsource[colnames[ikeynum]];

    DataRow drdest = dtdest.Rows.Find(keys);
    if (null == drdest) dtdest.Rows.Add(drsource.ItemArray);
   }
   for (int icolnum = 0; icolnum < dtdest.Columns.Count;)
   {
    if (colnames.Contains(dtdest.Columns[icolnum].ColumnName))
    {
     icolnum++;
     continue;
    }
    dtdest.Columns.Remove(dtdest.Columns[icolnum].ColumnName);
   }
   return (dtdest);
  }

  private void button2_Click(object sender, EventArgs e)
  {
   rtb.Clear();

   DataTable dtwork = new DataTable();
   dtwork.Columns.Add("DY", typeof(int));
   dtwork.Columns.Add("ID", typeof(int));
   dtwork.Columns.Add("NAME", typeof(string));
   dtwork.Columns.Add("COUNT", typeof(int));

   SetDataRow(dtwork, 1, 1, "CG", 1);
   SetDataRow(dtwork, 1, 1, "IR", 1);
   SetDataRow(dtwork, 1, 1, "RY", 1);
   SetDataRow(dtwork, 1, 1, "SR", 3);
   SetDataRow(dtwork, 1, 1, "VR", 30);
   SetDataRow(dtwork, 1, 1, "VR", 3);
   SetDataRow(dtwork, 1, 1, "GN", 1);
   SetDataRow(dtwork, 1, 2, "F2", 1);
   SetDataRow(dtwork, 1, 3, "GI", 4);
   SetDataRow(dtwork, 1, 4, "CJ", 1);
   SetDataRow(dtwork, 7, 1, "MX", 1);
   SetDataRow(dtwork, 7, 1, "C2", 1);
   SetDataRow(dtwork, 7, 1, "IR", 1);
   SetDataRow(dtwork, 7, 1, "RY", 1);
   SetDataRow(dtwork, 7, 1, "SR", 2);

   // 行データ取得
   rtb.AppendText("機種一覧取得(重複削除)\r\n");
   DataTable dttemp = Distinct(dtwork, "NAME");

   DataRow[] arryrow = null;
   try
   {
    dttemp.TableName = "DISTINCT";

    string folder = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
    if (dttemp.DataSet != null)
    {
     string file = System.IO.Path.Combine(folder, "DataSet.XML");
     dttemp.DataSet.WriteXml(file, XmlWriteMode.WriteSchema);
    }
    else
    {
     string file = System.IO.Path.Combine(folder, "DataTable.XML");
     dttemp.WriteXml(file, XmlWriteMode.WriteSchema);
    }

    rtb.AppendText("ソート\r\n");
    arryrow = dttemp.Select("", "NAME");
    if (arryrow.Length <= 0)
    {
     rtb.AppendText("arryrow.length <= 0\r\n");
     return;
    }
    rtb.AppendText("成功\r\n");
   }
   catch (Exception ex)
   {
    rtb.AppendText(ex.Message + "\r\n");
   }
  }
 }
}
==================================================

引用返信 編集キー/
■84398 / inTopicNo.11)  Re[8]: Selectを使ってエラーが出た時の原因
□投稿者/ 夜叉丸 (66回)-(2017/06/27(Tue) 18:50:23)
色々試してみたのですが、
やはり、原因はわかりませんでした。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -