質問するログイン新規登録

質問編集履歴

4

【該当のソースコード】修正

2017/05/23 00:31

投稿

yoshin
yoshin

スコア39

title CHANGED
File without changes
body CHANGED
@@ -163,7 +163,7 @@
163
163
  {
164
164
  book = GetOpenFile(filePath);
165
165
  sheets = GetSheets(book);
166
- sheet = GetSheet(sheets, sheetName);
166
+ sheet = GetSheet(sheets, 1);
167
167
  int lastRow = 65537;
168
168
  int lastColumn = 256;
169
169
  cells = GetCells(sheet);
@@ -220,13 +220,6 @@
220
220
  {
221
221
  return book.GetType().InvokeMember("Worksheets", BindingFlags.GetProperty, null, book, null);
222
222
  }
223
- // シート名からSheetを取得
224
- public object GetSheet(object sheets, string sheetName)
225
- {
226
- object[] parameters = new object[1];
227
- parameters[0] = sheetName;
228
- return sheets.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, sheets, parameters);
229
- }
230
223
  // シートインデックスからSheetを取得
231
224
  public object GetSheet(object sheets, int index)
232
225
  {

3

【発生している問題・エラーメッセージ】にファイルサイズ追加

2017/05/23 00:31

投稿

yoshin
yoshin

スコア39

title CHANGED
File without changes
body CHANGED
@@ -7,6 +7,7 @@
7
7
  ファイル選択ボタンをクリックしてエクセルファイルのデータを取得しています。
8
8
  同じファイルを選択して複数回実行したときに、
9
9
  1~6回目は処理が成功するのですが、7回目でエラーが発生します。
10
+ ※ファイルのサイズは522KB(65537行,256列)です。
10
11
  なお、上記の問題はVisual Studioのビルドのプラットフォームターゲットをx86とし、
11
12
  64bitのマシン環境で実行すると発生します。
12
13
  ※事情によりプラットフォームターゲットをx86にしています。

2

ソースコード修正

2017/05/22 07:04

投稿

yoshin
yoshin

スコア39

title CHANGED
File without changes
body CHANGED
@@ -6,22 +6,18 @@
6
6
  ###発生している問題・エラーメッセージ
7
7
  ファイル選択ボタンをクリックしてエクセルファイルのデータを取得しています。
8
8
  同じファイルを選択して複数回実行したときに、
9
- 1~3回目は処理が成功するのですが、4回目でエラーが発生します。
9
+ 1~6回目は処理が成功するのですが、7回目でエラーが発生します。
10
-
11
10
  なお、上記の問題はVisual Studioのビルドのプラットフォームターゲットをx86とし、
12
11
  64bitのマシン環境で実行すると発生します。
13
12
  ※事情によりプラットフォームターゲットをx86にしています。
14
13
  プラットフォームターゲットをAny CPU にすると発生しないことまではわかりました。
15
14
 
16
15
  【エラー発生箇所】
17
- DaoExcelFileクラスのReadFileメソッド内の
16
+ DaoExcelFileクラスのReadFileメソッド
18
- エクセルのRangeを配列にセットするステートメント
19
-
20
17
  ```
21
18
  【エラーメッセージ】
22
19
  プログラムを続行するための十分なメモリがありませんでした
23
20
  ```
24
-
25
21
  ###該当のソースコード
26
22
  ```ここに言語を入力
27
23
  public partial class Form1 : Form
@@ -32,17 +28,13 @@
32
28
  {
33
29
  InitializeComponent();
34
30
  }
35
-
36
31
  //ファイル選択ボタンクリック
37
32
  private void button1_Click(object sender, EventArgs e)
38
33
  {
39
- //ファイルの形式をセット
40
34
  var selectFileFormat = "Excel";
41
35
  //ユーザーファイルを選択してデータを読み込み
42
36
  FileReadWriteController.ReadUserInfoFile(selectFileFormat, out userFile);
43
-
44
37
  }
45
-
46
38
  //ファイルからデータを読み込み、書込みをコントロールするクラス
47
39
  public static class FileReadWriteController
48
40
  {
@@ -51,23 +43,13 @@
51
43
  public static bool ReadUserInfoFile(
52
44
  string selectFileFormat, out UserInfoFile userInfoFile)
53
45
  {
54
- //ファイルを開くダイアログのインスタンスを作成
55
46
  OpenFileDialog ofd = new OpenFileDialog();
56
- //ダイアログを表示する
57
47
  if (ofd.ShowDialog() == DialogResult.OK)
58
48
  {
59
- //ファイル形式によってケースわけ
60
- switch (selectFileFormat)
61
- {
62
- case "Excel":
63
- userInfoFile = new UserInfoFileExcel();
49
+ userInfoFile = new UserInfoFileExcel();
64
- userInfoFile.FilePath = ofd.FileName;
50
+ userInfoFile.FilePath = ofd.FileName;
65
- userInfoFile.ReadData();
51
+ userInfoFile.ReadData();
66
- return true;
52
+ return true;
67
- default:
68
- userInfoFile = null;
69
- return false;
70
- }
71
53
  }
72
54
  else
73
55
  {
@@ -76,37 +58,39 @@
76
58
  }
77
59
  }
78
60
  }
79
-
61
+ //ファイルの抽象クラス
62
+ abstract public class MyFile
63
+ {
64
+ public string FilePath;
65
+ public DataTable FileData;
66
+ public MyFile()
67
+ {
68
+ FileData = new DataTable();
69
+ }
70
+ public abstract void ReadData();
71
+ }
80
72
  //ユーザー情報情報ファイルの抽象クラス
81
73
  abstract public class UserInfoFile : MyFile
82
74
  {
83
75
  //省略
84
-
85
76
  }
86
-
87
77
  //Excel形式のユーザー情報ファイル
88
78
  public class UserInfoFileExcel : UserInfoFile
89
79
  {
90
80
  public override void ReadData()
91
81
  {
92
- //Excelファイルのデータを取得
93
82
  using (var excelApp = new DaoExcelFile())
94
83
  {
95
84
  excelApp.ReadFile(FilePath, FileData, "Info");
96
85
  excelApp.Quit();
97
86
  }
98
-
99
87
  }
100
88
  }
101
-
102
89
  //Excelクラス
103
90
  public class DaoExcelFile : IDisposable
104
91
  {
105
- // Excelアプリケーションオブジェクト
106
92
  private object xlsApplication = null;
107
- // Workbooksオブジェクト
108
93
  private object xlsBooks = null;
109
- // Excelアプリケーションオブジェクト
110
94
  protected object XlsApplication
111
95
  {
112
96
  get
@@ -120,7 +104,7 @@
120
104
  return xlsApplication;
121
105
  }
122
106
  }
123
-
107
+
124
108
  // Workbooksオブジェクト
125
109
  protected object Workbooks
126
110
  {
@@ -165,10 +149,6 @@
165
149
  // 対象ファイルの対象シートのデータをデータテーブルにセットする
166
150
  public void ReadFile(string filePath, DataTable fileData, string sheetName)
167
151
  {
168
- //対象シートは1枚目
169
- int sheetIndex = 1;
170
- //非可視に設定
171
- Visible = false;
172
152
  object book = null;
173
153
  object sheets = null;
174
154
  object sheet = null;
@@ -180,27 +160,17 @@
180
160
 
181
161
  try
182
162
  {
183
- //ブックを取得する
184
163
  book = GetOpenFile(filePath);
185
- //ワークシートコレクションを取得する
186
164
  sheets = GetSheets(book);
187
- //シートを取得する
188
165
  sheet = GetSheet(sheets, sheetName);
189
- //シートインデックスの取得
190
- sheetIndex = (int)sheet.GetType().InvokeMember("Index", BindingFlags.GetProperty, null, sheet, null);
191
- //シートの最終行を取得する
192
166
  int lastRow = 65537;
193
- //シートの最終列を取得する
194
167
  int lastColumn = 256;
195
- //cellsを取得
196
168
  cells = GetCells(sheet);
197
- //範囲を取得する基準セルを取得
198
169
  cella = GetCell(cells, 1, 1);
199
170
  cellb = GetCell(cells, lastRow, lastColumn);
200
- ////対象範囲を取得
201
171
  targetRange = GetRange(sheet, cella, cellb);
202
172
 
203
- //*********3回目の実行でここでエラーが発生する
173
+ //*********ここでエラーが発生する
204
174
  //*********エラー内容:"プログラムを続行するための十分なメモリがありませんでした"
205
175
  //オブジェクトの2次元配列へセット
206
176
  //以降この配列にアクセスすることで処理を高速化
@@ -219,6 +189,31 @@
219
189
  }
220
190
  }
221
191
 
192
+ // Excelファイルを開いてオブジェクトを返す
193
+ public object GetOpenFile(string xlsFilePath)
194
+ {
195
+ object[] parameters = new object[15];
196
+ parameters[0] = xlsFilePath;
197
+ parameters[1] = Type.Missing;
198
+ parameters[2] = Type.Missing;
199
+ parameters[3] = Type.Missing;
200
+ parameters[4] = Type.Missing;
201
+ parameters[5] = Type.Missing;
202
+ parameters[6] = Type.Missing;
203
+ parameters[7] = Type.Missing;
204
+ parameters[8] = Type.Missing;
205
+ parameters[9] = Type.Missing;
206
+ parameters[10] = Type.Missing;
207
+ parameters[11] = Type.Missing;
208
+ parameters[12] = Type.Missing;
209
+ parameters[13] = Type.Missing;
210
+ parameters[14] = Type.Missing;
211
+ object openFile = new object();
212
+ openFile = Workbooks.GetType().InvokeMember("Open", BindingFlags.InvokeMethod, null, Workbooks, parameters);
213
+ return openFile;
214
+
215
+ }
216
+
222
217
  // Sheetsを取得
223
218
  public object GetSheets(object book)
224
219
  {
@@ -261,7 +256,6 @@
261
256
  }
262
257
  }
263
258
  }
264
-
265
259
  ```
266
260
 
267
261
  ###試したこと

1

【発生している問題・エラーメッセージ】にビルド環境による違いを追記。【該当のソースコート】コード変更

2017/05/22 07:00

投稿

yoshin
yoshin

スコア39

title CHANGED
File without changes
body CHANGED
@@ -6,8 +6,13 @@
6
6
  ###発生している問題・エラーメッセージ
7
7
  ファイル選択ボタンをクリックしてエクセルファイルのデータを取得しています。
8
8
  同じファイルを選択して複数回実行したときに、
9
- 1,2回目は処理が成功するのですが、3回目でエラーが発生します。
9
+ 1~3回目は処理が成功するのですが、4回目でエラーが発生します。
10
10
 
11
+ なお、上記の問題はVisual Studioのビルドのプラットフォームターゲットをx86とし、
12
+ 64bitのマシン環境で実行すると発生します。
13
+ ※事情によりプラットフォームターゲットをx86にしています。
14
+ プラットフォームターゲットをAny CPU にすると発生しないことまではわかりました。
15
+
11
16
  【エラー発生箇所】
12
17
  DaoExcelFileクラスのReadFileメソッド内の
13
18
  エクセルのRangeを配列にセットするステートメント
@@ -21,39 +26,33 @@
21
26
  ```ここに言語を入力
22
27
  public partial class Form1 : Form
23
28
  {
24
- private UserInfoFile userInfoFile;
29
+ private UserInfoFile userFile;
25
30
 
26
31
  public Form1()
27
32
  {
28
33
  InitializeComponent();
29
34
  }
30
-
31
-
35
+
32
36
  //ファイル選択ボタンクリック
33
37
  private void button1_Click(object sender, EventArgs e)
34
38
  {
35
39
  //ファイルの形式をセット
36
40
  var selectFileFormat = "Excel";
37
41
  //ユーザーファイルを選択してデータを読み込み
38
- FileReadWriteController.ReadUserInfoFile(selectFileFormat, out userInfoFile);
42
+ FileReadWriteController.ReadUserInfoFile(selectFileFormat, out userFile);
39
43
 
40
44
  }
41
-
42
- /// <summary>
45
+
43
- /// ファイルからデータを読み込み、書込みをコントロールするクラス
46
+ //ファイルからデータを読み込み、書込みをコントロールするクラス
44
- /// </summary>
45
47
  public static class FileReadWriteController
46
48
  {
47
-
48
49
  ///ユーザー情報ファイルを選択して読み込み、
49
50
  ///読み込んだデータをユーザー情報ファイルオブジェクトのDataTabaleにセットする
50
51
  public static bool ReadUserInfoFile(
51
52
  string selectFileFormat, out UserInfoFile userInfoFile)
52
53
  {
53
-
54
54
  //ファイルを開くダイアログのインスタンスを作成
55
55
  OpenFileDialog ofd = new OpenFileDialog();
56
-
57
56
  //ダイアログを表示する
58
57
  if (ofd.ShowDialog() == DialogResult.OK)
59
58
  {
@@ -62,7 +61,6 @@
62
61
  {
63
62
  case "Excel":
64
63
  userInfoFile = new UserInfoFileExcel();
65
- //ファイルの内容を読み込む
66
64
  userInfoFile.FilePath = ofd.FileName;
67
65
  userInfoFile.ReadData();
68
66
  return true;
@@ -70,50 +68,23 @@
70
68
  userInfoFile = null;
71
69
  return false;
72
70
  }
73
-
74
71
  }
75
72
  else
76
73
  {
77
74
  userInfoFile = null;
78
75
  return false;
79
76
  }
80
-
81
77
  }
82
78
  }
83
79
 
84
-
85
- /// <summary>
86
- /// ファイルの抽象クラス
87
- /// </summary>
88
- abstract public class MyFile
89
- {
90
- public string FilePath;
91
- //エクセルから取得したセルデータをセットするDataTable
92
- public DataTable FileData;
93
-
94
- //コンストラクタ
95
- public MyFile()
96
- {
97
- FileData = new DataTable();
98
- }
99
-
100
- //指定したファイルの内容をFileDataメンバーにセットする
101
- public abstract void ReadData();
102
-
103
- }
104
-
105
- /// <summary>
106
- /// ユーザー情報情報ファイルの抽象クラス
80
+ //ユーザー情報情報ファイルの抽象クラス
107
- /// </summary>
108
81
  abstract public class UserInfoFile : MyFile
109
82
  {
110
83
  //省略
111
84
 
112
85
  }
113
86
 
114
- /// <summary>
115
- /// Excel形式のユーザー情報ファイル
87
+ //Excel形式のユーザー情報ファイル
116
- /// </summary>
117
88
  public class UserInfoFileExcel : UserInfoFile
118
89
  {
119
90
  public override void ReadData()
@@ -128,9 +99,7 @@
128
99
  }
129
100
  }
130
101
 
131
- /// <summary>
132
- /// Excelクラス
102
+ //Excelクラス
133
- /// </summary>
134
103
  public class DaoExcelFile : IDisposable
135
104
  {
136
105
  // Excelアプリケーションオブジェクト
@@ -151,7 +120,7 @@
151
120
  return xlsApplication;
152
121
  }
153
122
  }
154
-
123
+
155
124
  // Workbooksオブジェクト
156
125
  protected object Workbooks
157
126
  {
@@ -164,29 +133,13 @@
164
133
  return xlsBooks;
165
134
  }
166
135
  }
167
-
168
136
  //Dispose
169
137
  public void Dispose()
170
138
  {
171
- Dispose(true);
172
- GC.SuppressFinalize(this);
173
- }
174
-
175
- protected virtual void Dispose(bool disposing)
176
- {
177
- if (disposing)
178
- {
179
- }
180
-
181
139
  ReleaseComObject(xlsBooks);
182
140
  ReleaseComObject(xlsApplication);
183
141
  }
184
142
 
185
- ~DaoExcelFile()
186
- {
187
- Dispose(false);
188
- }
189
-
190
143
  // COMオブジェクトのリリース
191
144
  public void ReleaseComObject(object target)
192
145
  {
@@ -209,16 +162,13 @@
209
162
  XlsApplication.GetType().InvokeMember("Quit", BindingFlags.InvokeMethod, null, XlsApplication, null);
210
163
  }
211
164
 
212
- /// <summary>
213
- /// 対象ファイルの対象シートのデータをデータテーブルにセットする
165
+ // 対象ファイルの対象シートのデータをデータテーブルにセットする
214
- /// </summary>
215
- /// <param name="filePath">対象ファイルのパス</param>
216
- /// <param name="fileData">データのセット先のデータテーブル</param>
217
- /// <param name="sheetName">対象シート名</param>
218
- /// <returns></returns>
219
166
  public void ReadFile(string filePath, DataTable fileData, string sheetName)
220
167
  {
221
-
168
+ //対象シートは1枚目
169
+ int sheetIndex = 1;
170
+ //非可視に設定
171
+ Visible = false;
222
172
  object book = null;
223
173
  object sheets = null;
224
174
  object sheet = null;
@@ -230,37 +180,31 @@
230
180
 
231
181
  try
232
182
  {
233
- //Excelファイルを開いてオジェクトにセする ※GetOpenFileはDaoExcelFileクラスに実装しているが省略
183
+ //ブックを取得する
234
184
  book = GetOpenFile(filePath);
235
- //ワークシートコレクションを取得する ※GetSheetsはDaoExcelFileクラスに実装しているが省略
185
+ //ワークシートコレクションを取得する
236
186
  sheets = GetSheets(book);
237
- //シートを取得する ※GetSheetはDaoExcelFileクラスに実装しているが省略
187
+ //シートを取得する
238
188
  sheet = GetSheet(sheets, sheetName);
239
189
  //シートインデックスの取得
240
190
  sheetIndex = (int)sheet.GetType().InvokeMember("Index", BindingFlags.GetProperty, null, sheet, null);
241
- //シートの最終行を取得する ※GetLastRowIndexはDaoExcelFileクラスに実装しているが省略
191
+ //シートの最終行を取得する
242
- int lastRow = GetLastRowIndex(book, sheetIndex);
192
+ int lastRow = 65537;
243
- //シートの最終列を取得する ※GetLastColumnIndexはDaoExcelFileクラスに実装しているが省略
193
+ //シートの最終列を取得する
244
- int lastColumn = GetLastColumnIndex(book, sheetIndex);
194
+ int lastColumn = 256;
245
- //cellsを取得 ※GetCellsはDaoExcelFileクラスに実装しているが省略
195
+ //cellsを取得
246
196
  cells = GetCells(sheet);
247
- //範囲を取得する基準セルを取得 ※GetCellはDaoExcelFileクラスに実装しているが省略
197
+ //範囲を取得する基準セルを取得
248
198
  cella = GetCell(cells, 1, 1);
249
199
  cellb = GetCell(cells, lastRow, lastColumn);
250
- ////対象範囲を取得 ※GetRangeはDaoExcelFileクラスに実装しているが省略
200
+ ////対象範囲を取得
251
201
  targetRange = GetRange(sheet, cella, cellb);
252
202
 
253
-
254
203
  //*********3回目の実行でここでエラーが発生する
255
204
  //*********エラー内容:"プログラムを続行するための十分なメモリがありませんでした"
256
205
  //オブジェクトの2次元配列へセット
257
206
  //以降この配列にアクセスすることで処理を高速化
258
207
  obj1 = (System.Object[,])targetRange.GetType().InvokeMember("Value2", BindingFlags.GetProperty, null, targetRange, null);
259
-
260
-
261
- //DataTableに取得した配列の値をセットする ※SetDataToDataTableはDaoExcelFileクラスに実装しているが省略
262
- SetDataToDataTable(obj1, fileData);
263
-
264
208
  }
265
209
  finally
266
210
  {
@@ -275,9 +219,49 @@
275
219
  }
276
220
  }
277
221
 
222
+ // Sheetsを取得
223
+ public object GetSheets(object book)
224
+ {
225
+ return book.GetType().InvokeMember("Worksheets", BindingFlags.GetProperty, null, book, null);
226
+ }
227
+ // シート名からSheetを取得
228
+ public object GetSheet(object sheets, string sheetName)
229
+ {
230
+ object[] parameters = new object[1];
231
+ parameters[0] = sheetName;
232
+ return sheets.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, sheets, parameters);
233
+ }
234
+ // シートインデックスからSheetを取得
235
+ public object GetSheet(object sheets, int index)
236
+ {
237
+ object[] parameters = new object[1];
238
+ parameters[0] = index;
239
+ return sheets.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, sheets, parameters);
240
+ }
241
+ // Cellsを取得
242
+ public object GetCells(object sheet)
243
+ {
244
+ return sheet.GetType().InvokeMember("Cells", BindingFlags.GetProperty, null, sheet, null);
245
+ }
246
+ // Cellを取得
247
+ public object GetCell(object cells, int row, int column)
248
+ {
249
+ object[] parameters = new Object[2];
250
+ parameters[0] = row;
251
+ parameters[1] = column;
252
+ return cells.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, cells, parameters);
253
+ }
254
+ // Rangeを取得
255
+ public object GetRange(object sheet, object cell1, object cell2)
256
+ {
257
+ object[] parameters = new Object[2];
258
+ parameters[0] = cell1;
259
+ parameters[1] = cell2;
260
+ return sheet.GetType().InvokeMember("Range", BindingFlags.GetProperty, null, sheet, parameters);
261
+ }
278
262
  }
263
+ }
279
264
 
280
- }
281
265
  ```
282
266
 
283
267
  ###試したこと