БлогNot. Об использовании матричных функций Excel в Visual Studio

Об использовании матричных функций Excel в Visual Studio

Для использования в программе на псевдоC++ от Микрософт богатых вычислительных возможностей Excel, по идее, достаточно к своему проекту Visual C++/CLI (Windows Forms) добавить ссылку на COM-объект Microsoft Excel 14.0 Object Library (или Вашу версию Excel): меню Проект, Свойства, Список Общие свойства, вкладка COM, кнопка Добавить новую ссылку..., Обзор, выбрать COM-объект Microsoft Excel 14.0 Object Library (или ваша версия Excel вместо 14).

Кстати, нажав комбинацию клавиш Ctrl+Alt+J, можно посмотреть, что именно мы подключили, в Обозревателе объектов.

1. Если Office установлен корректно, с обычными функциями Excel сложностей не возникнет, например, здесь мы получаем из Excel число Пи и функцию возведения в степень, считая площадь круга с радиусом R и "отдавая" результат в текстовое поле textBox1:

auto XL = gcnew Microsoft::Office::Interop::Excel::Application();
double R=1.;
double S = XL->WorksheetFunction->Pi()*XL->WorksheetFunction->Power(R,2); //получили результат выполнения функций Excel
textBox1->Text = "S = " + S;
XL->Quit();

2. С матричными функциями всё немного иначе, в частности, в учебниках и инете встречается неправильный код вида:

array<double,2> ^ A = { {1, 12, 3},{-1, 1, 5},{0, 1, 1} };
array<double> ^ L = { 6, 3, 5 }; 
 //или array<double> ^ L = gcnew array<double>(n);
auto XL1 = gcnew Microsoft::Office::Interop::Excel::Application();
double det_A = XL1->Application->WorksheetFunction->MDeterm(A);
textBox1->Text += "Det(A)="+Convert::ToString(det_A)+"\n";
Object ^ oA = XL1->Application->WorksheetFunction->MInverse(A);
Object ^ X = XL1->Application->WorksheetFunction->MMult(oA, L);
array<Object^,2> ^ Xd = (array<Object^,2> ^)X; 
 // Чтобы ответ приобрел индексированные свойства, преобразуем его в массив
textBox1->Text += String::Format
 ("\r\nНеизвестные равны:\r\nX1 = {0}; X2 = {1}; X3 = {2}.",Xd[1, 1], Xd[2, 1], Xd[3, 1]); 
 // Получаем двумерный массив, индексы которого начинаются с единицы

(здесь решается СЛАУ размерности 3x3). Работать это не будет ("неверный результат выполнения функции MMult"), потому что Excel, как и Ваш учитель математики, чётко различает контексты вектор-строки и вектор-столбца, к тому же, функция MMult (умножение матриц) хочет видеть только двумерные данные. Правильной второй строкой кода будет такая:

array<double,2> ^ L = { {6}, {3}, {5} };

Именно и только двумерная индексация матрицы из 3 строк и 1 столбца.

3. Не всегда с офисными функциями дело обстоит столь же гладко. Например, согласно доке, функция Max (поиск максимального из чисел) имеет аж 30 (!) обязательных аргументов. И если он у вас всего один, вместо недостающих приходится писать Type::Missing. В C# такой глупости нет, там есть опциональные параметры и значения по умолчанию для них.

Код для вычисления Excel'евской функцией максимального из 9 чисел, введённых в левые верхние ячейки компонента DataGridView с именем dataGridView1, будет иметь вот такой жуткий вид:

const int height=3,width=3;
array<double,2> ^ A=gcnew array<double,2>(height,width);
for (int i=0; i<height; i++)
for (int j=0; j<width; j++) {
 A[i,j]=0; //а лучше "минус большое число", если не хотим специально считать не-числа как нули
 try {
  A[i,j] = 
   System::Double::Parse(dataGridView1->Rows[i]->Cells[j]->Value->ToString());
 } catch (...) {};
}
auto XL1 = gcnew Microsoft::Office::Interop::Excel::Application();
double  Res = XL1->Application->WorksheetFunction->Max(A,
Type::Missing,Type::Missing,Type::Missing,Type::Missing,Type::Missing,
Type::Missing,Type::Missing,Type::Missing,Type::Missing,Type::Missing,
Type::Missing,Type::Missing,Type::Missing,Type::Missing,Type::Missing,
Type::Missing,Type::Missing,Type::Missing,Type::Missing,Type::Missing,
Type::Missing,Type::Missing,Type::Missing,Type::Missing,Type::Missing,
Type::Missing,Type::Missing,Type::Missing,Type::Missing);
String ^ Result = "Max="+Convert::ToString(Res)+"\n";
MessageBox::Show(Result,"Ответ",MessageBoxButtons::OK,MessageBoxIcon::Information);
XL1->Quit();

10.04.2014, 22:59 [11694 просмотра]


теги: программирование ошибка excel c++/cli

показать комментарии (1)