Excel+C#

kira_006
Дата: 24.05.2014 07:40:01
Добрый день!

Вот задание по которому необходимо написать программу:
На языке C# реализовать программу, которая будет проводить корреляционный анализ результатов масштабного социологического
исследования The European Values Study 2012 года и актуальную статистику по рождаемости детей в тех же странах,
а также будет выделять наиболее яркие зависимости между общественными ценностями и показателями рождаемости детей.

Я создала форму на которой расположены следующие компоненты:
button1(открывает статистику в dataGridView),
button2(считает корреляцию),
dataGridView1(показывает статистику),
textBox1(показывает путь файла).

Вот код программы, который смогла написать(для открытия статистики):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;
using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;

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

        private void button1_Click(object sender, EventArgs e)
        {

            OpenFileDialog ofd = new OpenFileDialog(); //Задаем расширение имени файла по умолчанию. 
            ofd.DefaultExt = "*.xls;*.xlsx"; //Задаем строку фильтра имен файлов, которая определяет 
            //варианты, доступные в поле "Файлы типа" диалогового 
            //окна. 
            ofd.Filter = "Excel Sheet(*.xlsx)|*.xlsx"; //Задаем заголовок диалогового окна. 
            ofd.Title = "Выберите документ для загрузки данных";
            Excel.Application app = new Excel.Application();
            Excel.Workbook workbook;
            Excel.Worksheet NwSheet;
            Excel.Range ShtRange;
            DataTable dt = new DataTable();
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                textBox1.Text = ofd.FileName; workbook = app.Workbooks.Open(ofd.FileName, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value); //Устанавливаем номер листа из котрого будут извлекаться данные 
                //Листы нумеруются от 1 
                NwSheet = (Excel.Worksheet)workbook.Sheets.get_Item(1);
                ShtRange = NwSheet.UsedRange;
                for (int Cnum = 1; Cnum <= ShtRange.Columns.Count; Cnum++)
                {
                    dt.Columns.Add(new DataColumn((ShtRange.Cells[1, Cnum] as Excel.Range).Value2.ToString()));
                }
                dt.AcceptChanges();
                string[] columnNames = new String[dt.Columns.Count];
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    columnNames[0] = dt.Columns[i].ColumnName;
                }
                for (int Rnum = 2; Rnum <= ShtRange.Rows.Count; Rnum++)
                {
                    DataRow dr = dt.NewRow();
                    for (int Cnum = 1; Cnum <= ShtRange.Columns.Count; Cnum++)
                    {
                        if ((ShtRange.Cells[Rnum, Cnum] as Excel.Range).Value2 != null)
                        {
                            dr[Cnum - 1] = (ShtRange.Cells[Rnum, Cnum] as Excel.Range).Value2.ToString();
                        }
                    }
                    dt.Rows.Add(dr);
                    dt.AcceptChanges();
                }
                dataGridView1.DataSource = dt;
                app.Quit();
            }
            else Application.Exit();
        }


        private void button2_Click(object sender, EventArgs e)
        {
            
        }
    }
}


Помогите написать код для button2(считает корреляцию, т.е. при нажатии на кнопку необходимо, чтобы в ячейку "B35"
записывалась формула "=КОРРЕЛ(B2:AS2;B33:AS33)" и все изменения в Excel должны быть отображены в dataGridView1).
igr_ok
Дата: 24.05.2014 13:31:50
kira_006,

NwSheet= NwSheet.get_Range("B35", "B35"); 
NwSheet.Formula="=КОРРЕЛ(B2:AS2;B33:AS33)";
//получаем результат
object a=NwSheet.Value2;

Потом добавляем в DataTable строку и присваиваем значение во 2-м столбце

Теперь про ужасный код
if (ofd.ShowDialog() == DialogResult.OK)
{...}
else Application.Exit();

Закрывать приложение только потому, что пользователь не выбрал файл, слишком жестоко. Впрочем, возможно вы хотели только закрыть Excel. Тогда нужен
app.Quit();
А еще сразу возникает вопрос,а зачем мы открывали Excel, если пользователь ничего не сделал. И тут уже становится понятно, что нам нужен метод, который будет принимать в качестве параметра имя файла и что-то там делать. И вообще уничтожение объектов Excel лучше помещать в finally блока try...catch.
string[] columnNames = new String[dt.Columns.Count];
Массив объявляется, инициализируется и... нигде не используется. Так что он вам не нужен дважды: он не используется и у вас уже есть коллекция dt.Columns, содержащая те же данные.
Считывание данных из Excel по одной ячейке низкоэффективно. Чем больше ячеек, тем больше времени это действие займет. Для этого лучше использовать ADO.NET.
Обращение к конкретной ячейке "B35" превращает вашу программу в приложение, которое может работать только с одним листом Excel, что снижает ее практическую ценность. Злой преподаватель может добавить/удалить в таблицу Excel один столбец или одну стоку и прога уже будет работать некорректно. Лучше работать с номерами строк и столбцов.

Как бы делал задание я.
Считал бы данные с помощью ADO.NET в DataTable. Отобразил в гриде. После нажатия кнопки "Корреляция" произвел бы вычисления с ячейками DataTable. Формула корреляции есть здесь:. Показал бы результат вычисления в отдельном компоненте.
igr_ok
Дата: 24.05.2014 13:37:04
igr_ok
Формула корреляции есть здесь
http://exceltip.ru/как-рассчитать-коэффициент-корреляц/
kira_006
Дата: 26.05.2014 09:55:59
igr_ok,
спасибо большое за помощь.

я вставила такой код:
private void button2_Click(object sender, EventArgs e)
        {

            NwSheet = NwSheet.get_Range("B35", "B35");
            NwSheet.Formula = "=КОРРЕЛ(B2:AS2;B33:AS33)";
            //получаем результат
            object a = NwSheet.Value2;
            dataGridView1.DataSource = dt;
            DataRow MyRow = dt.NewRow();
            MyRow["Австрия"] = a;
            dt.Rows.Add(MyRow);
            dt.AcceptChanges();
        
        }


Выдает ошибку: "Неявное преобразование типа Microsoft.Office.Interop.Excel.Range в Microsoft.Office.Interop.Excel.Worksheet".
Может я пропустила какую то директиву using или еще что-то не так написала?
Shocker.Pro
Дата: 26.05.2014 10:27:22
kira_006
NwSheet = NwSheet.get_Range("B35", "B35");
вы присваиваете переменной типа Лист значение типа Диапазон, о чем вам и говорит компилятор

используйте переменную нужного типа
igr_ok
Дата: 26.05.2014 10:30:35
kira_006
igr_ok,
спасибо большое за помощь.

я вставила такой код:
private void button2_Click(object sender, EventArgs e)
        {

            NwSheet = NwSheet.get_Range("B35", "B35");
            NwSheet.Formula = "=КОРРЕЛ(B2:AS2;B33:AS33)";
            //получаем результат
            object a = NwSheet.Value2;
            dataGridView1.DataSource = dt;
            DataRow MyRow = dt.NewRow();
            MyRow["Австрия"] = a;
            dt.Rows.Add(MyRow);
            dt.AcceptChanges();
        
        }


Выдает ошибку: "Неявное преобразование типа Microsoft.Office.Interop.Excel.Range в Microsoft.Office.Interop.Excel.Worksheet".
Может я пропустила какую то директиву using или еще что-то не так написала?
Прошу прощения, немножко запутался в ваших переменных. Не NwSheet, а ShtRange
kira_006
Дата: 26.05.2014 10:57:24
igr_ok,
после замены в коде на ShtRange, ошибок не выдает, но и программа ничего не делает.
После нажатия на "Корреляцию" выходит такое окошко.

В чем может быть проблема?
kira_006
Дата: 26.05.2014 11:02:56
kira_006
igr_ok,
после замены в коде на ShtRange, ошибок не выдает, но и программа ничего не делает.
После нажатия на "Корреляцию" выходит такое окошко.

В чем может быть проблема?


Может быть я не правильно прибавила строку в DataTable?
EDUARD SAPOTSKI
Дата: 26.05.2014 11:36:33
Прикольно.
А Вы не замужем?
kira_006
Дата: 26.05.2014 11:41:33
EDUARD SAPOTSKI,
По моему Вы ошиблись темой или форумом)