Форум программистов, компьютерный форум, киберфорум
C#: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71

Выборка из БД в DataGridView: Почему последняя отмеченная строка не попадает в новый запрос

04.08.2014, 20:21. Показов 2390. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток! Помогите новичку разобраться.
Есть форма для работы с базой Access. таблица отображается в гриде:
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
OleDbConnection connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=baza.accdb;Jet OLEDB:Database Password=12345678;");
OleDbDataAdapter adapter = new OleDbDataAdapter();
System.Data.DataTable dt = new System.Data.DataTable();
 
public void LoadGrid()
        {
            try
            {
                adapter.SelectCommand = new OleDbCommand("select * from katalog", connection);
 
                dt.Clear();
                adapter.Fill(dt);
                grid.DataSource = dt;
 
                GridStyle();
                
                connection.Open();
                adapter.SelectCommand.ExecuteNonQuery();
                connection.Close();
 
                rbtnName.Checked = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                connection.Close();
            }
        }
В базе есть логическое поле (checkbox). По нажатию в меню на "Печать" строки в которых checkbox==true попадают в новый запрос:

C#
1
2
3
4
5
6
7
8
9
10
11
12
public void SelectRowsToPrint()
        {
            for (int i = 0; i < grid.RowCount; i++)
            {
                if((bool)grid.Rows[i].Cells[1].Value == true)
                {
                    str = grid.Rows[i].Cells[0].Value.ToString();
                    strSelectPrint += str + ", ";
                }
            }
            strSelectPrint = strSelectPrint.Substring(0, strSelectPrint.Length - 2);            
        }
И Grid заполняется по новому запросу:

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
private void LoadGridPrint()
        {
            OleDbConnection connPrint = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=baza.accdb;Jet OLEDB:Database Password=12345678;");
            OleDbDataAdapter adapPrint = new OleDbDataAdapter();
            System.Data.DataTable dtPrint = new System.Data.DataTable();
 
            SelectRowsToPrint();
 
            try
            {
                adapPrint.SelectCommand = new OleDbCommand("select nazvanie, artikul, cena_prodazhi from katalog where id in ("+strSelectPrint+")", connPrint);
 
                dtPrint.Clear();
                adapPrint.Fill(dtPrint);
                grid.DataSource = dtPrint;
 
                connPrint.Open();
                adapPrint.SelectCommand.ExecuteNonQuery();
                connPrint.Close();
 
                GridPrintStyle();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                connPrint.Close();
            }
        }
После чего уже новый Grid экспортируется в Excel:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private void menuPrint_Click_1(object sender, EventArgs e)
        {
            LoadGridPrint();
            GridPrintStyle();
 
            Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
            string path = System.Windows.Forms.Application.StartupPath + @"\export.xls";
            ExcelApp = new Microsoft.Office.Interop.Excel.Application();
            ExcelApp.Workbooks.Open(path);
 
            ExcelApp.Visible = true;
            ExcelApp.UserControl = true;
 
            for (int i = 0; i < grid.Rows.Count; i++)
            {
                for (int j = 0; j < grid.ColumnCount; j++)
                {
                    ExcelApp.Cells[i + 2, j + 1] = grid.Rows[i].Cells[j].Value;
                }
            }
 
            LoadGrid();
        }
И Grid перегружается полной таблицей из базы.

Вопроса 2:
1) Почему последняя отмеченная строка не попадает в новый запрос (по какой-то причине checkbox в последней отмеченной строке читается как false хотя отмечен как true)
2) И почему поле с checkbox'ом перемещается из столбца 2 в 4, хотя при запуске таблица этим же запросом формируется правильно.

Надеюсь доступно объяснил проблему. Подскажите что не так или ткните носом в ссылку, поиском не нашел как решить подобную проблему. Заранее спасибо!
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.08.2014, 20:21
Ответы с готовыми решениями:

DataGridView. Не сохраняется последняя строка
Открывается дополнительное окно, в котором есть только элемент DataGridView, который привязан к таблице в бд. Обработчик события закрытия...

Чем является отмеченная строка?
Всем Привет! Будьте добры, подскажите, чем являются отмеченные строки на приложенных картинках? Буду очень признателен!

Обновление SQLite БД через DataGridView - обновляется только последняя строка
Добрый всем день. Возникла проблема в обновлении бд sqlite через dataGridView. Обновляется, только последняя строка, а при обновлении более...

14
 Аватар для kodv
1449 / 1121 / 347
Регистрация: 11.04.2011
Сообщений: 2,621
05.08.2014, 05:48
Лучший ответ Сообщение было отмечено Hoffman как решение

Решение

Цитата Сообщение от Hoffman Посмотреть сообщение
Почему последняя отмеченная строка не попадает в новый запрос (по какой-то причине checkbox в последней отмеченной строке читается как false хотя отмечен как true)
Попробуйте выполнять grid.EndEdit() перед тем, как считывать значение из ячейки грида. Впоне возможно грид на момент вызова метода SelectRowsToPrint еще находится в режиме редактирования.
Цитата Сообщение от Hoffman Посмотреть сообщение
почему поле с checkbox'ом перемещается из столбца 2 в 4, хотя при запуске таблица этим же запросом формируется правильно
Я и в шар магический пробовал смотреть, и на кофейную гущу, и даже валенок за забор кинул, но увидеть код, который находится в методе GridStyle, так и не смог. Именно внутри этого метода скрыта причина указанного вами поведения.

Кстати, появился встречный вопрос:
DbCommand (OleDbCommand является наследником DbCommand), можно выполнить тремя способами: ExecuteReader, ExecuteScalar и ExecuteNonQuery. ExecuteReader возвращает DbReader, с помощью которого можно прочитать результирующий набор процедуры (результат выполнения SELECT'а внутри процедуру). ExecuteScalar возвращает значение первого столбца из первого строки результирующего набора. ExecuteNonQuery ни какого результирующего набора не возвращает. DataAdapter - это совокупность комманд разного назначения: для выборки, для добавления. для изменения и для удаления данных. Внутри метода DataAdapter.Fill открывается соединение, если оно было закртыо, выполняется SelectCommand.ExecuteReader, из которого заполняется таблица, передеваемая в Fill в качестве параметра, после чего закрывается подключение, если оно изначально было закрыто. То есть, чтобы заоплнить таблицу результирующим набором из DataAdapter.SelectCommand, достаточно вызывать метод DataAdapter.Fill.

Надеюсь, доступно объяснил? А теперь, внимание, вопросы:
1. Зачем в следующих кусках кода вы вызываете ExecuteNonQuery, который не возвращает результирующего набора, для SelectCommand, которая существует ради того, чтобы возвращать результирующий набор?
2. Зачем вы вообще вставили следующие куски кода в своей программе, если ранее вы используете метод DataAdapter.Fill, который прекрасно и правильно отрабатывает?
C#
1
2
3
                connection.Open();
                adapter.SelectCommand.ExecuteNonQuery();
                connection.Close();
C#
1
2
3
                connPrint.Open();
                adapPrint.SelectCommand.ExecuteNonQuery();
                connPrint.Close();
1
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71
05.08.2014, 08:54  [ТС]
Цитата Сообщение от kodv Посмотреть сообщение
Я и в шар магический пробовал смотреть, и на кофейную гущу, и даже валенок за забор кинул, но увидеть код, который находится в методе GridStyle, так и не смог. Именно внутри этого метода скрыта причина указанного вами поведения.
Сорри, действительно совсем забыл про метод GridStyle(). Вот он:
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
public void GridStyle()
        {
            grid.Columns[1].HeaderText = "V";
            grid.Columns[2].HeaderText = "Название";
            grid.Columns[3].HeaderText = "Артикул";
            grid.Columns[4].HeaderText = "Приход (общее кол-во)";
            grid.Columns[5].HeaderText = "Цена (по приходу)";
            grid.Columns[6].HeaderText = "Общая стоимость (по приходу)";
            grid.Columns[7].HeaderText = "Наценка";
            grid.Columns[8].HeaderText = "Цена продажи";            
            grid.Columns[9].HeaderText = "Скидка 10%";
            grid.Columns[10].HeaderText = "Кол-во продано по скидке 10%";
            grid.Columns[11].HeaderText = "Скидка 20%";
            grid.Columns[12].HeaderText = "Кол-во продано по скидке 20%";
            grid.Columns[13].HeaderText = "Продано (без скидки)";
            grid.Columns[14].HeaderText = "Доход";
            grid.Columns[15].HeaderText = "Чистая прибыль";
            grid.Columns[16].HeaderText = "Заказ";
            grid.Columns[17].HeaderText = "Доставка";
 
            grid.Columns[1].Width = 30;
            grid.Columns[2].Width = 240;
            grid.Columns[3].Width = 90;
            grid.Columns[4].Width = 125;
            grid.Columns[5].Width = 80;
            grid.Columns[6].Width = 125;
            grid.Columns[7].Width = 60;
            grid.Columns[8].Width = 90;
            grid.Columns[9].Width = 90;
            grid.Columns[10].Width = 125;
            grid.Columns[13].Width = 125;
            grid.Columns[14].Width = 110;
 
 
            LabelsSumm();
 
            this.grid.DefaultCellStyle.Font = new Font("Times New Roman", 12);
            this.grid.ColumnHeadersDefaultCellStyle.Font = new Font("Times New Roman", 10);
 
            grid.Sort(grid.Columns["id"], ListSortDirection.Ascending);
 
            grid.Columns[0].Visible = false;
        }
На всякий случай LabelsSumm():
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private void LabelsSumm()
        {
            long i = 0, k = 0, l = 0;
            for (int j = 0; j < grid.Rows.Count; j++) //сумма ячеек столбца "Общая стоимость (по приходу)"
                i += Convert.ToInt32(grid[5, j].Value);
 
            lblRasAll.Text = "Расходы (всего):" + Environment.NewLine + i.ToString();
 
            for (int j = 0; j < grid.Rows.Count; j++) //сумма ячеек столбца "Доход"
                k += Convert.ToInt32(grid[14, j].Value);
 
            lblDohAll.Text = "Доходы (всего):" + Environment.NewLine + k.ToString();
 
            for (int j = 0; j < grid.Rows.Count; j++) //сумма ячеек столбца "Чистая прибыль"
                l += Convert.ToInt32(grid[15, j].Value);
 
            lblPriAll.Text = "Чистая прибыль:" + Environment.NewLine + l.ToString();
        }
Цитата Сообщение от kodv Посмотреть сообщение
1. Зачем в следующих кусках кода вы вызываете ExecuteNonQuery, который не возвращает результирующего набора, для SelectCommand, которая существует ради того, чтобы возвращать результирующий набор?
2. Зачем вы вообще вставили следующие куски кода в своей программе, если ранее вы используете метод DataAdapter.Fill, который прекрасно и правильно отрабатывает?
Ответ прост до безобразия: данный кусок кода был найден на просторах интернета, оказался вполне рабочим, был адаптирован под себя и все....
Если я правильно понял без этого:
C#
1
2
3
                connection.Open();
                adapter.SelectCommand.ExecuteNonQuery();
                connection.Close();
метод будет работать так как мне нужно?
0
1057 / 864 / 195
Регистрация: 31.03.2010
Сообщений: 2,521
05.08.2014, 11:09
Hoffman,
1) Вообще удалите эти три строчки - все и без них будет работать
2) в конструкторе формы в DataGride вашем создайте ВСЕ столбцы(ПКМ-правка столбцов) запроса и в поле DataPropertyName укажите имя столбца в запросе. Это будет намного лучше чем вызывать GridStyle при каждом запросе.
3) перед привязкой данных (grid.DataSource = dt; ) укажите сначала
C#
1
grid.AutoGenerateColumns=false;
Добавлено через 4 минуты
собственно по вопросу: измененные данные гарантированно будут сохранены лишь после потери фокуса DataGrid'ом.
в любой другой момент нет гарантии что измененные данные сохранились
1
1057 / 864 / 195
Регистрация: 31.03.2010
Сообщений: 2,521
05.08.2014, 11:19
Далее следующий очень интересный вопрос: у вас УЖЕ загружены данные из БД,вы же для вывода печати выполняете полноценный запрос чтоб ПОВТОРНО загрузить данные.
Вот в свое время нашел простенькую реализацию печати грида, правда ее еще напильником следует шлифовать, но в 9 из 10 случаях вполне справляется
PrintDGV.zip
второй вариант использовать программы-отчеты(напр., Crystal Reports, сам использую FastReport)
0
1057 / 864 / 195
Регистрация: 31.03.2010
Сообщений: 2,521
05.08.2014, 11:36
Лучший ответ Сообщение было отмечено Hoffman как решение

Решение

а при выводе в Excel просто добавляем одну сточку, чтоб печатать только выделенные строчки:
C#
1
2
3
4
5
6
7
8
for (int i = 0; i < grid.Rows.Count; i++)
            {
                if(!(bool)grid.Rows[i].Cells[1].Value) continue;
                for (int j = 0; j < grid.ColumnCount; j++)
                {
                    ExcelApp.Cells[i + 2, j + 1] = grid.Rows[i].Cells[j].Value;
                }
            }
Добавлено через 2 минуты
З.Ы. тот же FastReport позволяет сохранить отчет в Excel(и другие форматы), а не только выводить на печать.

Добавлено через 10 минут

зачем для вычисления сумм 5 раз гонять цикл, почему нельзя выполнить все вычисления в одном цикле? к тому же лучше брать значения не из grid, а из DataTable
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private void LabelsSumm()
        {
            long i = 0, k = 0, l = 0;
            foreach(DataRow row in dt.Rows)
            { 
               //тут тип данных зависит от типа данных в БД. 
               //следует через отладчик посмотреть в row.ItemArray типы столбцов
               //сумма ячеек столбца "Общая стоимость (по приходу)"
                i += row.Field<Int32>(5); //тут лучше указывать имя столбца а не индекс - вдруг измените запрос
                //сумма ячеек столбца "Доход"
                k += row.Field<Int32>(14); 
               //сумма ячеек столбца "Чистая прибыль"
                l += row.Field<Int32>(15);
            }
            lblRasAll.Text = "Расходы (всего):" + Environment.NewLine + i.ToString();
            lblDohAll.Text = "Доходы (всего):" + Environment.NewLine + k.ToString();
            lblPriAll.Text = "Чистая прибыль:" + Environment.NewLine + l.ToString();
        }
1
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71
05.08.2014, 11:49  [ТС]
Цитата Сообщение от Learx Посмотреть сообщение
собственно по вопросу: измененные данные гарантированно будут сохранены лишь после потери фокуса DataGrid'ом.
в любой другой момент нет гарантии что измененные данные сохранились
Да, об этом знаю. От недостатка опыта, не подумал об этом сразу.

Цитата Сообщение от Learx Посмотреть сообщение
2) в конструкторе формы в DataGride вашем создайте ВСЕ столбцы(ПКМ-правка столбцов) запроса и в поле DataPropertyName укажите имя столбца в запросе. Это будет намного лучше чем вызывать GridStyle при каждом запросе.
Вот этот пункт не понятен.. ну кроме сознания столбцов в конструкторе..

Цитата Сообщение от Learx Посмотреть сообщение
Далее следующий очень интересный вопрос: у вас УЖЕ загружены данные из БД
Процесс выглядит следующим образом: Грид грузится при запуске программы методом LoadGrid(), далее в гриде в столбце с checkbox'ми отмечаем нужные для экспорта строки вызываем метод LoadGridPrint() из которого вызывается SelectRowsToPrint() читаем отмеченные строки и формируем в LoadGridPrint() новый запрос, которым и загружаем грид по новой. Дальше экспортируем уже по новой загруженный грид в эксель и перегружаем грид первичным запросом в методе LoadGrid() т.е. всю таблицу из Access.

Добавлено через 8 минут
Цитата Сообщение от Learx Посмотреть сообщение
а при выводе в Excel просто добавляем одну сточку, чтоб печатать только выделенные строчки:
Я правильно понимаю что при таком подходе отпадает необходимость грузить грид новым запросом?
Цитата Сообщение от Learx Посмотреть сообщение
зачем для вычисления сумм 5 раз гонять цикл, почему нельзя выполнить все вычисления в одном цикле? к тому же лучше брать значения не из grid, а из DataTable
За это отдельное спасибо!! Вечером все попробую и отпишусь.
0
1057 / 864 / 195
Регистрация: 31.03.2010
Сообщений: 2,521
05.08.2014, 12:00
Цитата Сообщение от Hoffman Посмотреть сообщение
Я правильно понимаю что при таком подходе отпадает необходимость грузить грид новым запросом?
именно так и есть
Цитата Сообщение от Hoffman Посмотреть сообщение
Вот этот пункт не понятен.. ну кроме сознания столбцов в конструкторе..
при выполнении grid.DataSourse=dt выполняется автоматическая генерация столбцов в DataGridView и после этого вы каждый раз редактируете заголовки и т.д.
Вместо этого можно один раз создать столбцы указать чтоб они не создавались(AutoGenerateColumns).
а чтоб было понятно из какого столбца в источнике данных DataTable следует брать значение созданному столбцу указываем в свойстве DataPropertyName столбца DataGridView имя соответственного столбца в DataTable.
1
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71
05.08.2014, 12:29  [ТС]
Цитата Сообщение от Learx Посмотреть сообщение
//тут тип данных зависит от типа данных в БД.
* * * * * * * *//следует через отладчик посмотреть в row.ItemArray типы столбцов
* * * * * * * *//сумма ячеек столбца "Общая стоимость (по приходу)"
* * * * * * * * i += row.Field<Int32>(5); //тут лучше указывать имя столбца а не индекс - вдруг измените запрос
Все поля в таблице, кроме ключевого, имеют тип string. Как в данном случае изменится ваш код?
0
 Аватар для kodv
1449 / 1121 / 347
Регистрация: 11.04.2011
Сообщений: 2,621
05.08.2014, 13:11
Hoffman, колонка у вас съезжает потому, что коллекция колонок не очищается полностью при изменении DataSource. Из коллекции удаляются ненужные колонки, добавляются отсутствующие. После экспорта в EXCEL колонки, которые были в гриде для экспорта в EXCEL, остаются на своих местах. аотсутствующие в выборке для экспорта в EXCEL колонки добавляются, начиная с позиции 3.
Вам вообще грид не нужен для экспорта в EXCEL. DataTable с головой хватит. По хорошему нужно вообще dt, по полю "V" (по крайней мере так вы его обозвали в методе GridStyle) отфильтровать и кинуть результат в EXCEL не заморачиваясь с перевыборкой данных. Но это требует более глобальных переделок, нежели отказ от грида при экспорте в EXCEL)
1
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71
05.08.2014, 21:34  [ТС]
Цитата Сообщение от Hoffman Посмотреть сообщение
Все поля в таблице, кроме ключевого, имеют тип string. Как в данном случае изменится ваш код?
Вопрос снят. Разобрался сам:
C#
1
2
3
4
5
6
7
8
9
10
 long i = 0, k = 0, l = 0;
            foreach (DataRow row in dt.Rows)
            {
                i += Convert.ToInt64(row.Field<string>("sum_cena_prihod"));
                k += Convert.ToInt64(row.Field<string>("dohod"));//сумма ячеек столбца "Доход"
                l += Convert.ToInt64(row.Field<string>("pribyl"));//сумма ячеек столбца "Чистая прибыль"
            }
            lblRasAll.Text = "Расходы (всего):" + Environment.NewLine + i.ToString();
            lblDohAll.Text = "Доходы (всего):" + Environment.NewLine + k.ToString();
            lblPriAll.Text = "Чистая прибыль:" + Environment.NewLine + l.ToString();
Добавлено через 6 часов 40 минут
С использованием всех советов получилось вот что:
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
private void menuPrint_Click_1(object sender, EventArgs e)
        {
            grid.EndEdit();
 
            Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
            string path = System.Windows.Forms.Application.StartupPath + @"\export.xls";
            ExcelApp = new Microsoft.Office.Interop.Excel.Application();
            ExcelApp.Workbooks.Open(path);
 
            ExcelApp.Visible = true;
            ExcelApp.UserControl = true;
 
            for (int i = 0; i < grid.Rows.Count; i++)
            {
                if ((bool)grid.Rows[i].Cells[1].Value)
                {
                    // мне нужны только три ячейки из каждой строки
                    ExcelApp.Cells[i + 2, 1] = grid.Rows[i].Cells[2].Value;
                    ExcelApp.Cells[i + 2, 2] = grid.Rows[i].Cells[3].Value;
                    ExcelApp.Cells[i + 2, 3] = grid.Rows[i].Cells[6].Value;
                }                
            }
 
            LoadGrid();
        }
Единственный минус то что в Excel создаются пустые строки, так как номер строки задается в цикле..
Варианта придумал два:
1) ручками уже в листе Excel скрыть пустые строки (или может это можно как то программно сделать? не нашел пока как)
2) отсортировать grid перед экспортом по логическому полю (почти как посоветовал kodv). Могу отсортировать по любому текстовому полю:
C#
1
2
3
DataView dv = dt.DefaultView;
dv.RowFilter = string.Format("nazvanie LIKE '%{0}%'", txbSort.Text);
grid.DataSource = dv;
как сюда прикрутить логическое поле не представляю..
0
 Аватар для kodv
1449 / 1121 / 347
Регистрация: 11.04.2011
Сообщений: 2,621
06.08.2014, 06:22
Hoffman, я же вам говорю, не используйте грид для экспорта. Используйте, допустим, отдельный DataView (отдельный для того, чтобы отображение в гриде ни как не менялось), и все будет проще и правильнее:
C#
1
2
3
4
5
6
7
8
DataView excelDataView = new DataView(dt);
excelDataView.RowFilter = "V = True"; // не знаю, как у вас это поле в таблице называется, в гриде вы его назвали "V", поэтому здесь его так и обозначаю
for(int i = 0; i < excelDataView.Count; ++i) // Проход будет только по тем строкам, которые удовлетворяют условию RowFilter
{
    ExcelApp.Cells[i + 2, 1] = excelDataView[i]["nazvanie"];
    ExcelApp.Cells[i + 2, 2] = excelDataView[i]["artikul"];
    ExcelApp.Cells[i + 2, 3] = excelDataView[i]["cena_prodazhi"];
}
1
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71
06.08.2014, 19:08  [ТС]
Всем огромное спасибо!!!! Окончательный метод выглядит так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void menuPrint_Click_1(object sender, EventArgs e)
        {
            grid.EndEdit();
 
            Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
            string path = System.Windows.Forms.Application.StartupPath + @"\export.xls";
            ExcelApp = new Microsoft.Office.Interop.Excel.Application();
            ExcelApp.Workbooks.Open(path);
 
            ExcelApp.Visible = true;
            ExcelApp.UserControl = true;
            
            DataView excelDV = new DataView(dt);
            excelDV.RowFilter = "marker = True";
            for (int i = 0; i < excelDV.Count; ++i) 
            {
                ExcelApp.Cells[i + 2, 1] = excelDV[i]["nazvanie"];
                ExcelApp.Cells[i + 2, 2] = excelDV[i]["artikul"];
                ExcelApp.Cells[i + 2, 3] = excelDV[i]["cena_prodazhi"];
            }
        }
Единственное что перестал срабатывать grid.EndEdit(), но это уже скорее не проблема а нюанс так как можно вручную снять фокус с редактируемой ячейки а потом экспортировать. Если есть другое решение подскажите )
0
1057 / 864 / 195
Регистрация: 31.03.2010
Сообщений: 2,521
07.08.2014, 16:14
C#
1
2
3
4
5
6
7
8
9
10
11
12
int RowIndex=2;
for (int i = 0; i < grid.Rows.Count; i++)
            {
                if ((bool)grid.Rows[i].Cells[1].Value)
                {
                    // мне нужны только три ячейки из каждой строки
                    ExcelApp.Cells[RowIndex, 1] = grid.Rows[i].Cells[2].Value;
                    ExcelApp.Cells[RowIndex, 2] = grid.Rows[i].Cells[3].Value;
                    ExcelApp.Cells[RowIndex, 3] = grid.Rows[i].Cells[6].Value;
                    RowIndex++;
                }                
            }
1
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71
07.08.2014, 16:20  [ТС]
Еще раз спасибо, Learx!!! Тему можно закрывать.)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
07.08.2014, 16:20
Помогаю со студенческими работами здесь

Почему считывается только последняя строка?
Добрый день. Я написал программу, которая удаляет второе слово в каждой строке. Суть в том, что, когда она читает исходный файл, почему-то...

Почему-то заполняется только последняя ячейка DataGridView
Нужно заполнить DataGridView случайными числами, но почему-то заполняет только последнюю ячейку. Заполнение проходит при загрузке формы,...

Datagridview как узнать, что текущая строка последняя (пустая для ввода новых данных пользователем)
у меня, например, в datagridview 3 стоки и 4-ая со звездочкой для ввода новых данных пустая свойство DBGrid1.CurrentCell.RowIndex не...

Работаю с файлом *.txt. Прога ведет себя странно если последняя строка файла пуста. Почему так?
Добрый день! Помогите пожалуйста с небольшой проблемой. Что хотел сделать: Есть текстовый файл, в нем содержатся любые...

Почему не удаляется единственная строка из DataGridView?
Объясните почему я не могу удалить методом this-&gt;dataGridView1-&gt;Rows-&gt;RemoveAt(0) единственную строку с индексом 0 на попытку подобного...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru