private void LoadCSVDataFileToolStripMenuItem_Click(object sender, EventArgs e)
 {
     try
     {
         if (AttributesListBox.SelectedItem == null)
         {
             throw new NullReferenceException("Набор атрибутов не задан!\nДля загрузки данных выберите набор атрибутов из списка.");
         }
         Stream         stream = null;
         OpenFileDialog OFD    = new OpenFileDialog
         {
             InitialDirectory = Directory.GetCurrentDirectory(),
             Filter           = "Данные, разделённые запятыми (*.csv)|*.csv|Все файлы (*.*)|*.*",
             FilterIndex      = 2,
             RestoreDirectory = true,
             Title            = "Загрузить данные"
         };
         if (OFD.ShowDialog() == DialogResult.OK)
         {
             if ((stream = OFD.OpenFile()) != null)
             {
                 if (Path.GetExtension(OFD.FileName) != ".csv")
                 {
                     throw new FileLoadException("Неверное расширение файла", OFD.FileName);
                 }
                 PyObject dataPyObject;
                 using (Py.GIL())
                 {
                     dataPyObject = PyModule.InvokeMethod("GetData", new PyObject[] { OFD.FileName.ToPython(), AttributeDataSets[AttributesListBox.SelectedItem.ToString()].Attributes });
                 }
                 int inputlength  = (int)dataPyObject["inputdata"].Length();
                 int outputlength = (int)dataPyObject["outputdata"].Length();
                 if (inputlength != outputlength)
                 {
                     throw new InvalidOperationException("Объём входных данных не соответствует объёму выходных!");
                 }
                 Data.DataSet    dataset         = new Data.DataSet(dataPyObject, 0, inputlength - 1);
                 DataGridViewRow dataGridViewRow = new DataGridViewRow();
                 dataGridViewRow.CreateCells(DataSetDataGridView);
                 dataGridViewRow.Cells[0].Value = Path.GetFileNameWithoutExtension(OFD.FileName);
                 dataGridViewRow.Cells[1].Value = dataset.Start;
                 dataGridViewRow.Cells[2].Value = dataset.Finish;
                 int before = DataSetDataGridView.RowCount;
                 DataSetDataGridView.Rows.Add(dataGridViewRow);
                 ResizeDataGridView(DataSetDataGridView, before);
                 AttributeDataSets[AttributesListBox.SelectedItem.ToString()].DataSets[Path.GetFileNameWithoutExtension(OFD.FileName)] = dataset;
                 MessageBox.Show("Файл данных загружен!", "Загрузка файла", MessageBoxButtons.OK, MessageBoxIcon.Information);
             }
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message, "Ошибка загрузки данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
         return;
     }
 }
        private void DataSetDataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            int old_value_start = -1, old_value_finish = -1;

            try
            {
                if (e.ColumnIndex == 0)
                {
                    Data.DataSet new_value = AttributeDataSets[AttributesListBox.SelectedItem.ToString()].DataSets[olddatasetkey];
                    AttributeDataSets[AttributesListBox.SelectedItem.ToString()].DataSets.Remove(olddatasetkey);
                    AttributeDataSets[AttributesListBox.SelectedItem.ToString()].DataSets[DataSetDataGridView["DataSetNameTB", e.RowIndex].Value.ToString()] = new_value;
                }
                else if (e.ColumnIndex == 1)
                {
                    old_value_start  = AttributeDataSets[AttributesListBox.SelectedItem.ToString()].DataSets[DataSetDataGridView["DataSetNameTB", e.RowIndex].Value.ToString()].Start;
                    old_value_finish = AttributeDataSets[AttributesListBox.SelectedItem.ToString()].DataSets[DataSetDataGridView["DataSetNameTB", e.RowIndex].Value.ToString()].Finish;
                    int new_value_start = Int32.Parse(DataSetDataGridView[e.ColumnIndex, e.RowIndex].Value.ToString());
                    if (new_value_start >= old_value_finish)
                    {
                        throw new IndexOutOfRangeException("Номер начальной строки должен быть меньше номера конечной строки!");
                    }
                    if (new_value_start < 0)
                    {
                        throw new IndexOutOfRangeException("Номер начальной строки должен быть больше 0!");
                    }
                    if (new_value_start > AttributeDataSets[AttributesListBox.SelectedItem.ToString()].DataSets[DataSetDataGridView["DataSetNameTB", e.RowIndex].Value.ToString()].Max)
                    {
                        throw new IndexOutOfRangeException("Номер начальной строки не может превышать количество строк в наборе данных!");
                    }
                    AttributeDataSets[AttributesListBox.SelectedItem.ToString()].DataSets[DataSetDataGridView["DataSetNameTB", e.RowIndex].Value.ToString()].Start = new_value_start;
                }
                else if (e.ColumnIndex == 2)
                {
                    old_value_start  = AttributeDataSets[AttributesListBox.SelectedItem.ToString()].DataSets[DataSetDataGridView["DataSetNameTB", e.RowIndex].Value.ToString()].Start;
                    old_value_finish = AttributeDataSets[AttributesListBox.SelectedItem.ToString()].DataSets[DataSetDataGridView["DataSetNameTB", e.RowIndex].Value.ToString()].Finish;
                    int new_value_finish = Int32.Parse(DataSetDataGridView[e.ColumnIndex, e.RowIndex].Value.ToString());
                    if (new_value_finish < 0)
                    {
                        throw new IndexOutOfRangeException("Номер конечной строки должен быть больше 0!");
                    }
                    if (new_value_finish <= old_value_start)
                    {
                        throw new IndexOutOfRangeException("Номер конечной строки должен быть больше номера начальной строки!");
                    }
                    if (new_value_finish > AttributeDataSets[AttributesListBox.SelectedItem.ToString()].DataSets[DataSetDataGridView["DataSetNameTB", e.RowIndex].Value.ToString()].Max)
                    {
                        throw new IndexOutOfRangeException("Номер конечной строки не может превышать количество строк в наборе данных!");
                    }
                    AttributeDataSets[AttributesListBox.SelectedItem.ToString()].DataSets[DataSetDataGridView["DataSetNameTB", e.RowIndex].Value.ToString()].Finish = new_value_finish;
                }
            }
            catch (Exception ex)
            {
                if (e.ColumnIndex == 1 || e.ColumnIndex == 2)
                {
                    DataSetDataGridView["RowsFromTB", e.RowIndex].Value = old_value_start;
                    DataSetDataGridView["RowsTillTB", e.RowIndex].Value = old_value_finish;
                }
                MessageBox.Show(ex.Message, "Ошибка при изменении даннных", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }