Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
8 / 8 / 2
Регистрация: 30.01.2015
Сообщений: 157
1

Организовать проверку данных из Excel файла

07.08.2017, 08:33. Показов 2529. Ответов 12

Author24 — интернет-сервис помощи студентам
Подскажите как лучше организовать проверку. Есть Excel файл, в нем таблица, таблица четко определена, т.е. например 10 столбцов, в первом вводится только текст, во второй только цифры, в третьем дата и так далее. Естественно пользователи совершают ошибки. Мне нужно организовать проверки на правильность заполнения. Т.е. загружаю Excel файл в программку, в в верхнем DataGridView показываются данные с Excel файла и например подсвечивается строка с ошибкой другим цветом, в нижнем показываются ошибки в этой строке.
Ну например:
В верхнем подсвечивается строка красным цветом, а в нижнем сообщение - "неверный формат даты" или "это поле должно содержать только цифры".

Вот думаю, как это лучше сделать.
1 вариант: создать типизированный DataSet, в нем создать схемы моих таблиц. Потом грузить Excel файл в DataTable и этот DataTable сравнивать с схемой в DataSet

Никогда такое не делал, но нужно пробовать.

Или может есть более простой способ?

Добавлено через 9 минут
Когда то на c++ писал подобную проверку, но там проверку осуществлял при загрузке данных в сетку и если была ошибка, то окрашивал в определенный цвет ячейку. Только не знаю как это сделать лучше и эффективнее на C#
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.08.2017, 08:33
Ответы с готовыми решениями:

Организовать проверку введенных данных в TextBox
Доброго времени суток! Нужна помощь Подскажите как организовать проверку введенных данных в...

Чтение из файла (как организовать проверку на ошибку чтения?)
Как на C организовать проверку на ошибку чтения файла ? ( т.е если файл невозможно прочитать,...

Как грамотно организовать проверку типа данных
Проверяю массив данных на вычисляемость Дан какой-то массив с 1000 строками и 200 столбцами....

Как организовать проверку и смену данных по таймеру?
В базе есть таблица топ 5 игроков.Время для нахождения в топе час.И есть таблица очередей, куда...

12
360 / 287 / 76
Регистрация: 21.06.2016
Сообщений: 1,115
07.08.2017, 10:56 2
Дело всё в том, что не в каждом ексель-файле будет идти проверка, там просто строка с разным форматом отображения. Соответственно - придется во время загрузки с екселя загружать сразу же в строго типизированную таблицу с кастованием каждого из полей, и запихивать ошибки в правильный catch - он и выдаст ошибку при загрузке файла, а немного подпилив напильником - можно показать и номер строки с ошибкой.
Почему не подсвечивая - потому что всё равно невозможно работать с неправильными данными - поэтому пусть пользователь и исправляет свои ошибки до момента загрузки файла в программу.
1
8 / 8 / 2
Регистрация: 30.01.2015
Сообщений: 157
07.08.2017, 11:04  [ТС] 3
Как считаете, если сначала с excel загнать все в таблицу как есть, ну привязать эту таблицу к dgv чтоб наглядней было, а потом с этой таблицы грузить или сравнивать в типизированную таблицу и тогда в случае исключений выдавать ошибку и возможно подсвечивать строки с ошибками разными цветами?
0
997 / 356 / 135
Регистрация: 27.10.2006
Сообщений: 764
07.08.2017, 13:23 4
Более простой способ воспользоваться встроенной "Проверкой данных" в самом Excel

https://support.office.com/ru-... f3ce5f7249

http://www.excel-vba.ru/chto-u... ka-dannyx/

http://officeprogs.ru/excel/pr... excel.html

http://excel2.ru/articles/prov... v-ms-excel
0
644 / 528 / 324
Регистрация: 20.05.2015
Сообщений: 1,469
09.08.2017, 03:33 5
Mudrec,
У каждой ячейки в dgv есть Errortext. Можно после проверки менять его значение у определенных ячеек с ошибками.
А закрасить можно потом так:
C#
1
2
3
4
        private void dataGridView1_CellErrorTextChanged(object sender, DataGridViewCellEventArgs e)
        {
                (sender as DataGridView).Rows[e.RowIndex].Cells[e.ColumnIndex].Style.BackColor = ((sender as DataGridView).Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText == "" ? Color.White : Color.Yellow);
        }

Не по теме:

Цитата Сообщение от hoolygan Посмотреть сообщение
Почему не подсвечивая - потому что всё равно невозможно работать с неправильными данными - поэтому пусть пользователь и исправляет свои ошибки до момента загрузки файла в программу.
К сожалению на практике все бывает не совсем так... Пользователь может подправить ячейки для корректной загрузки данных, но не может менять данные чтобы они соответствовали формулам не имея соответствующего документа (которого может и не быть:wall:). И тогда приходится иметь дело с тем с чем имеем.

1
hoolygan
09.08.2017, 09:15
  #6

Не по теме:

Цитата Сообщение от Aferuga Посмотреть сообщение
И тогда приходится иметь дело с тем с чем имеем
Приведу пример из своей практики - делал форму для пользователей - они загружают таблички с данными, где указаны SKU товаров и их цены (розница/опт/акция - ну как положено). Файлики по 300-700 тыс строк - не так и много - но достаточно. Далее нужно обновлять таблицы в БД числовыми значениями. И вот тут непорядок возникает - потому что вместо числа - там стоит что-то другое - дата, строка с текстом и т.д. Поэтому суть не в формулах, а именно типе значения и возможности его приведения к другому типу - именно это я и имел в виду, не формулы, а тип.

1
644 / 528 / 324
Регистрация: 20.05.2015
Сообщений: 1,469
10.08.2017, 08:47 7

Не по теме:

Цитата Сообщение от hoolygan Посмотреть сообщение
возможности его приведения к другому типу - именно это я и имел в виду, не формулы, а тип.
Я лишь привел пример почему подсветка может пригодится и стоит её задавать или нет зависит от предметной области.
Конечно можно не обрабатывать если сроки поджимают, или просто лень заморачиваться, но это вполне реализуемо.


К слову, насчет возможности приведения к нужному типу, можно грузить все данные изначально используя только строковый тип(который сконвертируется в большинстве случаев без ошибок), а потом уже в программе проверять что не может сконвертироваться в необходимый тип, затем подсветить и дать возможность поменять ручками + добавить навигацию по ошибкам чтобы пользователь долго не искал + небольший инструментарий для действий со всем массивом строк вроде замены, удаления пропущенных строк и т. д.
1
8 / 8 / 2
Регистрация: 30.01.2015
Сообщений: 157
11.08.2017, 08:29  [ТС] 8
Вот именно как то так и хочу организовать. Загрузил нужный диапазон в таблицу, таблицу в качестве источника привязал к dgv. Как лучше организовать проверку и подсветку?
0
360 / 287 / 76
Регистрация: 21.06.2016
Сообщений: 1,115
11.08.2017, 08:43 9
Mudrec, да разными способами, можно например организовать цикл по загруженной таблице (Вы же загружаете её не в контрол, а в DataTable, правильно же? ) - и потом добавить колонку с булевским значением 1/0 - есть или нету ошибки, а грид подпилить напильником на CustomDraw (чесно - не помню какое событие, потому что со стандартным не работаю), чтобы в зависимости от значения светил или нет строчку.
0
644 / 528 / 324
Регистрация: 20.05.2015
Сообщений: 1,469
14.08.2017, 02:22 10
Для начала определить порядок столбцов если необходимо(т. е. задать соответствие столбцов если идут в неправильном порядке), потом задавать проверку если что-то не конвертируется добавлять в список(см ниже) в том же цикле можно расставить ошибки по гриду, меняя у ячеек ErrorText (выше писал как подсветить конкретные ячейки). Список ошибок можно загрузить в listBox и дальше по клику переходить на соответствующую ячейку(связь по выбранному индексу).
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
private List<error> li_errors = new List<error>();
        public struct error
        {
            public int x,y;
            public string error_text;
            public error(int _x, int _y, string _error)
            {
                x = _x;
                y=_y;
                error_text = _error;//тут можно запилить обработку текста ошибки
            }
        }
1
8 / 8 / 2
Регистрация: 30.01.2015
Сообщений: 157
16.08.2017, 11:30  [ТС] 11
стараюсь делать примерно так, как вы писали. Загружаю Excel файл в dgv.
В обработчике событий dgvResult, пишу следущее

C#
1
2
3
4
5
6
7
8
private void dgvResult_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
     DataGridViewColumn column = dgvResult.Columns[e.ColumnIndex];
     ПроверкаДанных p = new ПроверкаДанных(ref dgvResult);
 
     if (column.Name == "nomer") p.CheckNomer(e);
     else if (column.Name == "dateBirth")  p.CheckDateBirth(e);      
}
В методах CheckNomer(e) и CheckDateBirth(e) провожу проверку данных и если есть ошибка, то с помощью метода AnnotateCell ставлю ErrorText = «Ошибка: это не число» или «Предупреждение: Не является датой», зависит от конкретной ошибки

C#
1
2
3
4
5
private void AnnotateCell(string errorMessage, DataGridViewCellValidatingEventArgs editEvent)
{
      DataGridViewCell cell = dgvResult.Rows[editEvent.RowIndex].Cells[editEvent.ColumnIndex];
      cell.ErrorText = errorMessage;            
}

В обработчике событий dgvResult
C#
1
2
3
4
5
6
7
8
9
private void dgvResult_CellErrorTextChanged(object sender, DataGridViewCellEventArgs e)
{
   (sender as DataGridView).Rows[e.RowIndex].Cells[e.ColumnIndex].Style.BackColor =
           ((sender as DataGridView).Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText == "" ?   
              Color.White : Color.Yellow);
 
   //Всю строку подсвечиваю красным  
   (sender as DataGridView).Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Pink;
 }

Вот то что получилось. Событие dgvResult_CellValidating происходит при выходе фокуса из ячейки, т.е. кликнул в ячейку мышкой, кликнул на другую ячейку и выполнилась проверка. Как сделать автоматически это? Написал цикл по всем ячейкам, но реально это занимает очень много времени.
C#
1
2
3
4
5
6
7
for (int i = 0; i < dgvResult.Rows.Count; i++)
{
     for (int j = 3; j < dgvResult.Columns.Count; j++)
     {
        dgvResult.CurrentCell = dgvResult.Rows[i].Cells[j];
     }
}
Как лучше это сделать?

Но даже после того как цикл выполнился, ошибки пометились, потом кликаешь на сортировку любого столбца dgvResult и вся подсветка ошибок пропадает. Как можно это исправить или оптимизировать?
0
644 / 528 / 324
Регистрация: 20.05.2015
Сообщений: 1,469
17.08.2017, 04:43 12
Цитата Сообщение от Mudrec Посмотреть сообщение
Как можно это исправить или оптимизировать?
1) Полная проверка нужна только один раз и её отчасти можно оптимизировать сделав проверку асинхронной(по крайней мере форма не будет казаться зависшей), к тому же я писал выше что лучше создать список ошибок и при дальнейших проверках обращаться к нему.
2) можно попробовать проверять datatable (здесь главное проконтролировать связь с гридом, оставив гриду только тот функционал который будет обрабатываться и не будет нарушать связь по координатам например убрать ручное добавление, удаление строк и т.д.), по крайней мере стараться как можно меньше использовать сам грид.
3) отрубить сортировку на фиг она будет поганить вообще все в любом случае, конечно можно её оставить и делать перезапуск всей проверки после каждой сортировки если очень хочется
4) выпилить проверку из cellValidating (вообще не знаю зачем тут использовать cellValidating) в отдельный метод входными данными которого будут координаты ячейки
ибо это уже костыль:
C#
1
dgvResult.CurrentCell = dgvResult.Rows[i].Cells[j];
5) если решили делать проверку с помощью класса то зачем запихивать туда целый грид?
Кликните здесь для просмотра всего текста
C#
1
2
3
4
string val = dgvResult.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();//возможно просто x y вместо e
ПроверкаДанных p = new ПроверкаДанных(val);
if (column.Name == "nomer") p.CheckNomer();
     else if (column.Name == "dateBirth")  p.CheckDateBirth();

либо
Кликните здесь для просмотра всего текста
C#
1
2
3
string val = dgvResult.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();//возможно просто x y вместо e
ПроверкаДанных p = new ПроверкаДанных(val, column.Name);
if (p.HasErrors) dgvResult.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = p.GetErrors();
1
360 / 287 / 76
Регистрация: 21.06.2016
Сообщений: 1,115
17.08.2017, 10:43 13
Вставлю и свои 5 копеек, попробую во всяком случае

1. Загружаете весь ексель в DataTable как есть, без проверок со строковыми полями.
2. Те колонки которые нужно проверить на валидность - запускаете цикл (Linq - тут разницы нет, только в красоте) - на TryConvert() - при ошибочном конвертировании ставите цифру какую-то, например "-1" - главное чтобы эта цифра однозначно указывала на ошибку чтобы нормальных данных небыло таких же.
3. После того, как выполнили эту процедуру на всех колонках, запускаете данные в грид.
4. Паралельно в гриде отрисовываете нужным цветом строки, в которых встречаются цифры-ошибки.

После этого можете и сортировать и мышкой клацать - но все проверки завершатся, так что будет не страшно.

Этим убираете у себя кучу проблем вроде валидации ячеек и передачей в отдельный класс грида (даже не таблицы - это АД!).
Попробуйте - думаю, что этим ускорите работу в тысячи раз, потому что работать будете с сырыми данными, а не с гридом.
1
17.08.2017, 10:43
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.08.2017, 10:43
Помогаю со студенческими работами здесь

Организовать ввод данных, проверку условий через условного оператора
z=ae^sinx +2.5 x&gt;0.3 a=1.5 надо составить программу через условный оператор...

Организовать проверку данных на ввод чисел в массив, которые не больше 5
Всем привет. Есть такой код #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;windows.h&gt;...

Как организовать проверку введенных пользователем данных на соответствие определенной маске?
Помогите, pls, разрешить проблему: Как организовать проверку введенных пользователем данных на...

Как грамотно и эфективно организовать проверку вводимых пользователем данных в textBox-ы?
Добрый день помогите решить задачу, или дайте идею как реализовать, может кто то с таким...


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

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