0 / 0 / 0
Регистрация: 06.07.2015
Сообщений: 56
1

Необрабатываемое исключение

24.07.2015, 11:19. Показов 2198. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
В VS2010 приведённый ниже код запускается без предупреждений и ошибок. Всё работает на ура как положено. Но когда я запускаю EXE-шник вне студии - выскакивает окошко с сообщением: Необрабатываемое исключение в приложении..... Индекс за пределами диапазона. Далее куча текста, но важно что ругается на строку в теле цикла. Всё равно после игнорирования, приложение запускается и выполняется корректно. Что посоветуете сделать?

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Kent.Boogaart.KBCsv;
 
namespace WindowsFormsApplication1
{
    public partial class Form1:Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            DataSet dataSt = new DataSet();//Будущий датасет для данных
            using (CsvReader reader = new CsvReader(@"C:\file.csv"))//Открыли файл КСВ
            {
                reader.ValueSeparator = Char.Parse(";");//Обязательно указывай, какой символ будет являться разделителем в твоём КСВ-файле. В моём случае это точка с запятой
                reader.ReadHeaderRecord();//Этот метод надо вызвать, прежде чем что-либо делать с файлом КСВ. Он считывает заголовок.
                reader.Fill(dataSt);//Закинули в наш ДатаСет новую таблицу со всеми данными из файла.
            }
          
            dataGridView1.DataSource = dataSt.Tables[0];//Всё, видим эти данные глазами
            dataGridView1.Columns.Add("Column9", "Часовой расход");
            dataGridView1.Columns.Add("Column10", "Суточный расход");
            for(int i=0;i<dataGridView1.Rows.Count;i++)
                dataGridView1.Rows[i].Cells[8].Value = Convert.ToDecimal(dataGridView1.Rows[i + 1].Cells[6].Value) - Convert.ToDecimal(dataGridView1.Rows[i].Cells[6].Value);
            
         
        }
    }
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.07.2015, 11:19
Ответы с готовыми решениями:

Необрабатываемое исключение в приложении
Привет всем, никогда ранее не писал на C# и вот решил написать что-то мелкое. Сделал, скомпилил,...

НЕобрабатываемое исключение в приложении
Здравствуйте. Пишу простое приложение. У меня на компе все работает. На другом компе выдает ошибку....

Необрабатываемое исключение в приложении
************** Текст исключения ************** System.NullReferenceException: Ссылка на объект не...

Путь к внешнему файлу / Необрабатываемое исключение в приложении
Здравствуйте! В программе на с# WF при наведении на картинку, она должна быть заменена на другую....

16
61 / 61 / 32
Регистрация: 30.07.2013
Сообщений: 178
24.07.2015, 15:26 2
Ошибка возникает в данном коде:
C#
1
dataGridView1.Rows[i + 1].Cells[6].Value
Для последней строки в гриде i + 1 будет ссылаться на строку для добавления данных, в ячейках которой нет данных.

Добавлено через 1 минуту
Если методу Convert.ToDecimal() передать null то вылезет ошибка.
0
0 / 0 / 0
Регистрация: 06.07.2015
Сообщений: 56
24.07.2015, 15:43  [ТС] 3
Спасибо ! Как можно проще обойти этот баг ?
0
Администратор
Эксперт .NET
16860 / 13248 / 5181
Регистрация: 17.03.2014
Сообщений: 27,076
Записей в блоге: 1
24.07.2015, 17:18 4
Андрей197000, "неожиданное" исключение возникает потому что при подключенном отладчике исключения в событии Form.Load игнорируются. Это нормальное поведение для платформы x64.

Что касается бага, то правильнее всего добавить вычисляемую колонку в DataTable. Класс DataGridView должен заниматься отображением данных, а не выступать как источник данных. Делается это примерно так:
C#
1
2
3
4
5
6
7
8
9
10
11
DataSet ds = new DataSet();
DataTable table = new DataTable();
table.Columns.Add(new DataColumn("col1", typeof(string)));
table.Columns.Add(new DataColumn("col2", typeof(string)));
table.Columns.Add(new DataColumn("col3", typeof(decimal), "Convert(col1,System.Decimal) + Convert(col2,System.Decimal)"));
ds.Tables.Add(table);
 
table.Rows.Add("1,1", "1,2");
table.Rows.Add("2,1", "2,2");
table.Rows.Add("3,1", "3,2");
table.Rows.Add("4,1", "4,2");
0
0 / 0 / 0
Регистрация: 06.07.2015
Сообщений: 56
21.09.2015, 10:46  [ТС] 5
Вернулся к когда-то обсуждаемой теме. Не могу разобраться с вычислениями в в DataTable, как мне порекомендовал "OwenGlendower". Как например в коде реализовать, чтобы в восьмом столбце отображались результаты вычитания соседних ячеек шестого столбца? Для dataGridView я это так делал:
C#
1
2
for(int i=0;i<dataGridView1.Rows.Count;i++)
                dataGridView1.Rows[i].Cells[8].Value = Convert.ToDecimal(dataGridView1.Rows[i + 1].Cells[6].Value) -            Convert.ToDecimal(dataGridView1.Rows[i].Cells[6].Value);
0
Администратор
Эксперт .NET
16860 / 13248 / 5181
Регистрация: 17.03.2014
Сообщений: 27,076
Записей в блоге: 1
21.09.2015, 14:37 6
Андрей197000, что именно тебе непонятно в моем примере? У DataColumn есть свойство Expression которое может содержать произвольные выражения которые могут ссылаться на другие колонки по имени. В примере выше expression задается через конструктор DataColumn.
0
0 / 0 / 0
Регистрация: 06.07.2015
Сообщений: 56
21.09.2015, 15:25  [ТС] 7
Как это работает?:
C#
1
2
3
4
table.Rows.Add("1,1", "1,2");
table.Rows.Add("2,1", "2,2");
table.Rows.Add("3,1", "3,2");
table.Rows.Add("4,1", "4,2");
0
Администратор
Эксперт .NET
16860 / 13248 / 5181
Регистрация: 17.03.2014
Сообщений: 27,076
Записей в блоге: 1
21.09.2015, 15:33 8
Андрей197000, ты не туда смотришь. В следующем фрагменте создается DataTable с тремя колонками.
C#
1
2
3
4
DataTable table = new DataTable();
table.Columns.Add(new DataColumn("col1", typeof(string)));
table.Columns.Add(new DataColumn("col2", typeof(string)));
table.Columns.Add(new DataColumn("col3", typeof(decimal), "Convert(col1,System.Decimal) + Convert(col2,System.Decimal)"));
В строке №4 мы добавляем третью колонку и передаем конструктору вычисляемое выражение: "Convert(col1, System.Decimal) + Convert(col2, System.Decimal)". col1 и col2 это названия других колонок. Таким образом третья колонка будет равна сумме первых двух.

Соответственно когда далее мы заполняем таблицу данными
C#
1
2
3
4
table.Rows.Add("1,1", "1,2");
table.Rows.Add("2,1", "2,2");
table.Rows.Add("3,1", "3,2");
table.Rows.Add("4,1", "4,2");
мы указываем только значения первых двух колонок, а третья будет вычислена автоматически.
1
0 / 0 / 0
Регистрация: 06.07.2015
Сообщений: 56
25.09.2015, 14:55  [ТС] 9
К сожалению я не могу понять как конкретно в коде получить значения, например из шестого столбца после заполнения ридером таблицы (в моём случае).
0
Администратор
Эксперт .NET
16860 / 13248 / 5181
Регистрация: 17.03.2014
Сообщений: 27,076
Записей в блоге: 1
25.09.2015, 21:22 10
Андрей197000, а я не понимаю как это связано с вычисляемыми столбцами. Вот пример чтения 6 столбца.
C#
1
2
3
4
5
DataTable table = ...;
foreach (DataRow row in table.Rows)
{
    string smth = (string)row[5]; // 6-й столбец
}
0
0 / 0 / 0
Регистрация: 06.07.2015
Сообщений: 56
06.07.2016, 08:23  [ТС] 11
Вернулся к своей старой программе (фрагмент кода в начале темы). Проблема в следующем: при больших размерах таблицы в файле *сsv загрузка в dataGridView1 идёт очень долго. Там в таблице часовой архив. Каждый час добавляется новая запись в файл. Как сделать чтобы в dataGridView1 загружались только последние, скажем 100 -150 строк, а не вся таблица?
0
Эксперт .NET
11991 / 8317 / 1266
Регистрация: 21.01.2016
Сообщений: 31,328
06.07.2016, 08:50 12
Андрей197000, самый простой способ - читать из файла только последние 100-150 записей...
0
0 / 0 / 0
Регистрация: 06.07.2015
Сообщений: 56
06.07.2016, 08:58  [ТС] 13
Мне это и нужно. Только как это реализовать? Перегруженный метод reader.Fill(dataSt, 150) читает например первые 150 записей.
0
Эксперт .NET
11991 / 8317 / 1266
Регистрация: 21.01.2016
Сообщений: 31,328
06.07.2016, 09:12 14
Андрей197000, скорее всего ручками. Открыть файловый поток, перемотать курсор на несколько килобайт от конца, прочитать и откинуть первую строку (она, скорее всего, будет неверная) и в цикле читать оставшиеся строки. Каждую прочитанную строку парсить, а результат записывать в виде DataRow в DataTable.

Как-то так.
0
Администратор
Эксперт .NET
16860 / 13248 / 5181
Регистрация: 17.03.2014
Сообщений: 27,076
Записей в блоге: 1
06.07.2016, 23:10 15
Цитата Сообщение от Андрей197000 Посмотреть сообщение
Как сделать чтобы в dataGridView1 загружались только последние, скажем 100 -150 строк, а не вся таблица?
Возможное решение это наследник TextReader который читает из CSV файла первую(ые) строку с заголовком + N последних строк и затем дает это прочитать. Накидал быстро простой вариант который подходит для небольшого количества строк.
CsvTailTextReader
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class CsvTailTextReader : TextReader
{
    StringReader r;
 
    public CsvTailTextReader(string path, int maxLines)
    {
        string firstLine;
        string[] lines = ReadLastLines(path, maxLines, out firstLine);
 
        string s = firstLine + string.Join("\r\n", lines);
        r = new StringReader(s);
    }
 
    public override int Peek() { return r.Peek(); }
    public override int Read() { return r.Read(); }
    public override int Read(char[] buffer, int index, int count) { return r.Read(buffer, index, count); }
    public override string ReadLine() { return r.ReadLine(); }
    public override Task<string> ReadLineAsync() { return r.ReadLineAsync(); }
    public override string ReadToEnd() { return r.ReadToEnd(); }
    public override Task<string> ReadToEndAsync() { return r.ReadToEndAsync(); }
 
    static string[] ReadLastLines(string path, int maxLines, out string firstLine)
    {
        firstLine = "";
        using (var reader = new StreamReader(path))
        {
            string line;
            var lines = new List<string>(maxLines);
            for (int i = 0; i < maxLines; i++)
            {
                line = reader.ReadLine();
                if (line == null) return lines.ToArray();
                if (line[0] == '#')
                {
                    firstLine += line + "\r\n";
                    i--;
                }
                else
                    lines.Add(line);
            }
 
            int idx = maxLines - 1;
            while ((line = reader.ReadLine()) != null)
            {
                idx++;
                if (idx == maxLines) idx = 0;
                lines[idx] = line;
            }
 
            if (idx == maxLines - 1) return lines.ToArray();
            var result = new string[maxLines];
            lines.CopyTo(idx + 1, result, 0, maxLines - idx - 1);
            lines.CopyTo(0, result, maxLines - idx - 1, idx + 1);
            return result;
        }
    }
}

Использование:
C#
1
2
3
4
5
6
7
using (var tailReader = new CsvTailTextReader(@"C:\file.csv", 150))
using (var csvReader = new CsvReader(tailReader))
{
    csvReader.ValueSeparator = ';';
    csvReader.ReadHeaderRecord();
    csvReader.Fill(dataSt);
}
1
191 / 180 / 114
Регистрация: 28.07.2013
Сообщений: 606
07.07.2016, 00:15 16
Андрей197000, вот ещё как вариант:
C#
1
2
3
4
5
6
var last_150 = File.ReadAllLines(@"C:\file.csv");
if(last_150.Length>=150){
    for (int i=last_150.Length-150;i<last_150.Length;i++){
        table.Rows.Add(last_150[i]);
    }
}
1
0 / 0 / 0
Регистрация: 06.07.2015
Сообщений: 56
07.07.2016, 08:03  [ТС] 17
Спасибо! Оба варианта работают.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.07.2016, 08:03
Помогаю со студенческими работами здесь

Необрабатываемое исключение ...
Создал прогу бд ,она у меня как курсовой проект собственно её мне надо продемонстрировать на компе...

Необрабатываемое исключение в приложении
Здравствуйте При выходе из режима сна стало выскакивать окно: Необрабатываемое исключение в...

Необрабатываемое исключение в приложении
Нажимаю на w,s,d,a и выскакивает такая ошибка. Как исправить? uses GraphABC, ABCobjects; var...

PascalABC.NET - подпрограмма. Необрабатываемое исключение в приложении
Здравствуйте! Уменя вопрос по поводу подпрограммы!(PascalABC.NET); Нажимаю на кнопку --&gt; прехожу...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru