Vba_расчеты
.pdfМИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования МОСКОВСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ «МАМИ»
В.И.Калядин
Решение задач в Excel на VBA
ПРИМЕНЕНИЕ ПРОГРАММНЫХ СРЕДСТВ В ПРОЕКТИРОВАНИИ АВТОМОБИЛЬНЫХ КОНСТРУКЦИЙ
Допущено УМО вузов РФ по образованию в области транспортных машин и транспортно-технологических комплексов в качестве
учебного пособия для студентов, обучающихся по специальности Автомобиле- и тракторостроение
Одобрено методической комиссией по математическим и естественнонаучным дисциплинам
МОСКВА 2011
УДК 681.3.06
Разработано в соответствии с Государственным образовательным стандартом ВПО 2000 г. для специальности Автомобиле- и тракторостроение на основе рабочей программы дисциплины «Информатика»
Рецензенты: с.н.с. ФГУП «ЦНИРТИ им. академика А.И.Берга», к.т.н. В.Ф.Блохина;
доцент кафедры «Автоматизация процессов управления», к.т.н. Ю.А.Савостьянок.
Работа подготовлена на кафедре "Информационные системы и дистанционные технологии"
Калядин В.И. Решение задач в Excel на VBA. Применение программных средств в проектировании автомобильных конструкций. Учебное пособие по дисциплине «Информатика» для студентов, обучающихся по специальности Автомобиле- и тракторостроение. М.: МАМИ, 2010. 48 с.: ил.
Пособие поможет закрепить и углубить знания по алгоритмизации и программированию и подготовить студентов к решению инженерных и научных задач в Excel на VBA.
©Калядин В.И.,2011.
©МГТУ «МАМИ», 2011.
2
Введение
В настоящем пособии рассматривается решение задач в Excel с использованием VBA (Visual Basic for Applications – визуального Бейсика для приложений). Освоение программирования на VBA позволяет выполнять расчеты в Excel более эффективно (на более высоком уровне), использовать макросы и функции пользователя. В пособии разбираются приѐмы решения задач с подключением макросов, приводятся примеры их написания, примеры использования процедур dll-библиотек и включения в Excel «функций, определѐнных пользователем». Задачи, приведѐнные в пособии, могут быть использованы как итоговые задания при завершении изучения программировании на VBA (и как темы заданий при дальнейшем изучении студентами численных методов).
1. Действия с массивами в Excel и в VBA 1.1. Процедуры ввода-вывода массивов
При решении задач в VBA ввод-вывод простых переменных из файла осуществляется операторам Input и Print, а из ячейки рабочего листа Excel по оператору присваивания вида X=Cells(2,3). Можно вводить из формы и выводить на форму с использованием элементов управления TextBox и Label. Но в этом случае удобнее использовать специально встроенные для этого в VBA функции InputBox и MsgBox. Табличная форма Excel удобна для представления массивов и матриц. Однако ввод-вывод массивов и матриц стандартными средствами VBA не всегда удаѐтся реализовать столь коротко и компактно как для простых переменных. Поэтому целесообразно заготовить для этого специальные процедуры и использовать их при решении задач для ввода-вывода массивов (одномерных) и матриц. Далее рассмотрены такие процедуры; их можно подключать для использования командами реактора VBA: File, Import File… как и другие модули, имена которых указаны в Приложении.
Вописанных ниже процедурах предполагается:
Индексы массивов должны начинаться с нуля.
Тип массива либо не должен объявляться, либо должен объявляться как Variant.
3
Вывод массива в файл № = NF или в окно отладки при NF = 0:
Sub PrnMas(A(), N, NF, AName$)
'Вывод массива A(N) с именем AName$ в файл № NF, в окно отладки при NF = 0.
S$ = "Массив " & AName$ & "(0:" & N & ")"
If NF = 0 Then Debug.Print S$ Else Print #NF, S$ For j = 0 To N
If NF = 0 Then Debug.Print A(j); Else Print #NF, A(j); Next j
If NF = 0 Then Debug.Print Else Print #NF, ""
End Sub
Ввод N+1 значений элементов вектора (одномерного массива) чтением из текущего места в файле NF:
Sub IptMas(A(), N, NF)
'Ввод элементов A(0),..,A(N) массива из файла № = NF, с клавиатуры при NF <= 0.
For j = 0 To N
If NF <= 0 Then
A(j) = Val(InputBox("Задайте элемент № " & j, "Ввод массива"))
Else
Input #NF, A(j)
End If Next j
End Sub
Пример 1.1 использования процедур IptMas, PrnMas для ввода (и вывода) из файла IptDat.txt чисел: 3, 2.5, 6, -2, 7, 13
Sub Test_IptMas() Dim A(2)
Open "IptDat.txt" For Input As #1 ' файл для чтения (из папки … по умолчанию)
Call |
IptMas(A, 2, 1) |
' |
вариант исх. данных ---> |
|
3 |
2.5 |
6 |
|
|
|
|
|
|
-2 |
7 |
13 |
|
|
|
|
|
|
|
|
|
|
Call |
PrnMas(A, 2, 0, "A") |
' |
результат вывода ---> |
|
Массив A(0:2) |
|||
Call |
IptMas(A, 2, 1) |
|
|
3 2,5 6 |
|
|||
|
|
|
|
|
|
|
Close 1
4
Call PrnMas(A, 2, 0, "A") ' результат вывода ---> |
Массив A(0:2) |
|
-2 7 13 |
||
End Sub |
||
|
Ввод в массив всех чисел (вплоть до конца) файла № =NF c определением их количества
Sub IptMasN(A(), N, NF) ' на входе: N=max индекс массива
'Ввод элементов A(0),..,A(N) массива из файла № = NF, с клавиатуры при NF <= 0.
Dim str As Variant For j = 0 To N
If NF <= 0 Then
str = InputBox("Задайте элемент № " & j & "или признак конца X", _ "Ввод массива")
If str = "x" Or str = "X" Then Exit For
A(j) = Val(str)
Else
If EOF(NF) Then Exit For Input #NF, A(j)
End If Next j
N = j – 1 ' на выходе: N= кол-во введѐнных данных-1 , но N<=max индекс массива)
End Sub
Пример 1.2 использования процедур IptMasN, PrnMas для ввода (и вывода) из файла IptDat.txt чисел: 3, 2.5, 6, -2, 7, 13 (числа могут следовать друг за другом по строкам и разделяться как запятыми, так и пробелами).
Sub Test_IptMasN() Dim A(6)
Open "IptDat.txt" For Input As #1 ' файл для чтения (из папки по умолчанию)
N=6: Call IptMasN(A, N, 1) ' |
вариант исх. данных ---> |
3 |
2.5 |
6 |
|
Close 1 |
|
-2 |
7 |
13 |
|
|
|
|
|||
Call PrnMas(A, N, 0, "A") ' |
результат вывода ---> |
Массив A(0:5) |
|||
End Sub |
|
3 |
2,5 |
6 -2 7 13 |
|
|
5 |
|
|
|
|
|
|
|
|
|
Вывод матрицы в файл № NF или в окно отладки
Sub PrnMatr(A(), M, N, NF, AName$)
'Вывод матрицы A с именем AName$ в файл № = NF, в окно отладки при NF = 0.
S$ = "Матрица " & AName$ & "(0:" & M & ", 0:" & N & ")"
If NF = 0 Then Debug.Print S$ Else Print #NF, S$ For i = 0 To M
For j = 0 To N
If NF = 0 Then Debug.Print Tab(10 * j + 1); FF(A(i, j), "##0.0##"), _ Else Print #NF, Tab(10 * j + 1); FF(A(i, j), "##0.0##"),
Next j
If NF = 0 Then Debug.Print Else Print #NF, "" Next i
End Sub
Function FF(x, frm As String) As String
FF = IIf(x > 0, " ", "-") & Format(Abs(x), frm) ' +числа c побелом в позиции знака
End Function
Ввод матрицы из файла № NF*
Sub IptMatr(A(), M, N, NF)
'Ввод матрицы A(M,N) из файла № = NF, с клавиатуры при NF <= 0.
For i = 0 To M For j = 0 To N
If NF <= 0 Then
A(i, j) = Val(InputBox("Задайте элемент строки № " & i & ", столбца № " & j, _ "Ввод матрицы"))
Else
Input #NF, A(i, j)
End If Next j
Next i
End Sub
* Замечание. Часто оказывается, что исходные данные из файла удобнее использовать в таблицах, перенося их туда из открываемого стандартными средствами
Excel файла.
6
Пример 1.3 использования процедур IptMatr, PrnMatr для ввода (и вывода) из файла IptDat.txt чисел: 3, 2.5, 6, -2, 7, 13 (числа – элементы матрицы удобно расположить в файле как в матрице - по три в строке, разделяя их пробелами или запятыми).
Sub Test_IptMatr() |
|
|
|
|
|
Dim A(1, 2) |
|
|
|
|
|
|
3 |
2.5 |
6 |
|
|
Open "IptDat.txt" For Input As #1 ' вариант исх. данных ---> |
|
||||
Call IptMatr(A, 1, 2, 1) |
|
-2 |
7 |
13 |
|
|
|
|
|
|
|
Close 1 |
|
|
|
||
Матрица A(0:1, 0:2) |
|||||
Call PrnMatr(A, 1, 2, 0, "A") ' результат вывода ---> |
3,0 |
2,5 |
6,0 |
|
|
End Sub |
-2,0 |
7,0 |
13,0 |
|
|
|
|
|
|
|
Вывод массива в диапазон ячеек строки
Sub FromMasToRow(ByVal Row, ByVal Column, ByRef A(), ByVal N)
Jc = Column |
Пример 1.4. Обращение и результат вывода |
|
|
|||
|
|
|
||||
For j = 0 To N |
Sub Row(): Dim A(1): A(0)=6: A(1)=7 |
|
|
|
||
|
|
|
|
|||
Cells(Row, Jc) = A(j) |
Call FromMasToRow (1, 2, A, 1) |
|
|
|
|
|
|
|
|
|
|
|
|
Jc = Jc + 1 |
End Sub |
A |
B |
C |
D |
|
Next j |
|
|
|
|
|
|
1 |
|
6 |
7 |
|
|
|
|
|
|
|
|||
End Sub |
|
|
|
|
|
|
Вывод массива в диапазон ячеек столбца |
|
|
|
|
|
|
Sub FromMasToColumn(ByVal Row, ByVal Column, ByRef A(), ByVal N) |
|
|
||||
' Вывод массива A(N) в диапазон ячеек $Row$Column:$(Row+N)$Column столбца |
||||||
Ir = Row |
|
|
|
|
|
|
For i = 0 To N |
Пример 1.5. Обращение и результат вывода |
|
A |
B |
||
|
|
|
|
|||
Cells(Ir, Column) = A(i) |
Sub Col(): Dim A(1): A(0)=11: A(1)=22 |
|
1 |
|
11 |
|
|
Call FromMasToColumn (1, 2, A, 1) |
|
|
|
||
Ir = Ir + 1 |
|
|
|
|
|
|
|
|
|
2 |
|
12 |
|
Next i |
End Sub |
|
|
|
||
|
|
|
|
|
|
End Sub
Вывод матрицы в диапазон ячеек рабочего листа Excel
Sub FromMatrToRange(ByVal Row, ByVal Column, ByRef A(), ByVal M, ByVal N) ' Вывод матрицы A(M,N) в диапазон ячеек Row$Column:$(Row+M)$(Column+N)
Ir = Row
7
For i = 0 To M
Jc = Column
For j = 0 To N Cells(Ir, Jc) = A(i, j)
Jc = Jc + 1
Next j
Ir = Ir + 1
Next i
End Sub
Пример 1.6 использования процедуры FromMatrToRange
Sub Test_FromMatrToRange() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Dim A(1, 2) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Open "IptDat.txt" For Input As # |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
2.5 |
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
Call IptMatr(A, 1, 2, 1) ' исх. данные ---> |
|
|
|
|
|
|
|
|
|
|
|
|
|||
-2 |
7 |
13 |
|
|
A |
|
B |
|
C |
|
D |
||||
|
|
|
|
|
|
||||||||||
Close 1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
|
|
3 |
|
|
2,5 |
|
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
Call FromMatrToRange(1, 2, A, 1, 2) ' результат вывода ---> |
|
|
|
|
|
|
|
|
|
|
|
||||
2 |
|
|
-2 |
|
|
7 |
|
|
13 |
|
|||||
|
|
|
|
|
|
|
|||||||||
End Sub |
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ввод массива из диапазона ячеек рабочего листа Excel
Sub FromRangeToMas(ByRef A(), ByVal N)
' Ввод массива A(N) из диапазона ячеек рабочего листа Excel
Dim R As Range
Set R = Application.InputBox(prompt:= "Укажите массив", Type:=8) For j = 0 To IIf(R.Count - 1 > N, N, R.Count - 1)
A(j) = R(j + 1)
Next j
End Sub
Пример 1.7 использования процедуры FromRangeToMas для ввода данных: |
|
|
|
|||||||||||||
Sub Test_FromRangeToMas() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A |
|
B |
|
|
C |
|
D |
|
E |
|
||||
Dim A(3) |
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
Call FromRangeToMas(A, 3) ' выделенные ячейки ---> |
|
1 |
|
|
|
11 |
|
|
12 |
|
13 |
|
14 |
|
||
|
|
|
|
|
|
|||||||||||
Debug.Print A(0); A(1); A(2); A(3) ' результат вывода ---> |
|
11 |
12 13 14 |
|
|
|
||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
End Sub |
|
|
|
|
|
|
|
|
|
|
|
|||||
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ввод матрицы из диапазона ячеек рабочего листа Excel
Sub FromRangeToMatr(ByRef A(), ByVal M, ByVal N)
' Ввод матрицы A(M,N) из диапазона ячеек рабочего листа Excel
Dim R As Range
Set R = Application.InputBox(prompt:="Укажите матрицу", Type:=8)
For i = 0 To M
If i >= R.Rows.Count Then Exit For For j = 0 To N
If j >= R.Columns.Count Then Exit For A(i, j) = R(i + 1, j + 1)
Next j Next i
End Sub
Пример 1.8 использования процедуры FromRangeToMatr для ввода |
||||||
даных: |
|
|
A |
B |
C |
D |
|
|
|
||||
Sub Test_FromRangeToMatr() |
|
1 |
|
11 |
12 |
13 |
|
|
|
||||
Dim A(1, 2) |
|
2 |
|
21 |
22 |
23 |
|
|
|
||||
Call FromRangeToMatr(A, 1, 2) ) |
' выделенные ячейки ---> |
|
|
|
|
|
Debug.Print A(0, 0); A(0, 1); A(0, 2) |
' результат вывода ---> |
11 12 13 |
|
|||
Debug.Print A(1, 0); A(1,1); A(1, 2) |
' результат вывода ---> |
21 22 23 |
|
|
End Sub
Замечание. При выделении объединения диапазонов процедура использует лишь первый указанный диапазон.
1.2. Изучение в Excel метода Гаусса
Задача A. Автоматизировать вычисления для практического изучения в Excel метода Гаусса решения систем линейных алгебраических уравнений (СЛАУ) с выбором главного элемента по столбцу.
Напомним один из основных методов решения СЛАУ – метод исключения Гаусса с выбором главного элемента по столбцу.
Решение системы начинается с прямого хода, который выполняется по шагам. На 1-ом ( k 1) шаге прямого хода с помощью первого уравнения исключают из последующих уравнений неизвестное xk (если ко-
9
эффициент при нѐм не равен нулю). Если этот коэффициент равен нулю, то можно переставить местами уравнения. Для гарантии вычислительной устойчивости перед исключением неизвестных из уравнений с k го по n ое выбирают и переставляют с k ым(I-ым) то уравнение (II-ое, см. СЛАУ к задаче A), в котором коэффициент (главный эле-
мент) при неизвестном |
xk |
|
наибольший по абсолютной величине: |
|||||||||||
|
2x1 |
1x2 |
1x3 |
7 |
(I) |
4x1 |
3x2 |
0x3 |
10 |
(II) |
||||
|
4x1 |
3x2 |
0x3 |
10 |
(II) |
|
2x1 |
|
1x2 |
1x3 |
7 |
|
||
СЛАУ к задаче A: |
|
|
(I) |
|||||||||||
|
|
2x |
|
3x |
11(III) |
|
|
|
2x |
|
3x 11(III) |
|||
2x |
2 |
2x |
|
2 |
||||||||||
|
1 |
|
3 |
|
|
|
1 |
|
|
3 |
|
|||
Исключение неизвестного |
|
xk x1 выполняют по схеме (см. нумерацию |
||||||||||||
уравнений): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4x1 3x2 0x3 10 |
|||
|
2x1 1x2 |
1x3 7 |
|
|
|||
|
|
|
3x 11 |
2x 2x |
2 |
||
|
1 |
3 |
(II)
(I ) I - (2/4) (II) (III ) (III) ( 2/4) (II)
4x1 3x2 |
0x3 |
10 (II) |
||
|
0 0.5x2 |
1x3 |
2 (I ) |
|
|
||||
|
0 3.5x |
2 |
3x |
16 (III ) |
|
|
3 |
|
На втором ( k 2 ) шаге также сначала выбирается главный элемент
среди коэффициентов при неизвестном xk x2 среди уравнений с k го |
||||||||||
по n ое и переставляют местами строки так, чтобы строка с главным |
||||||||||
элементом стала k ой : |
|
|
|
|
|
|
|
|||
4x1 3x2 |
0x3 10 (II) |
|
4x1 3x2 |
0x3 |
10 (II) |
|||||
|
0 0.5x2 |
1x3 |
2 (I ) |
|
|
0 3.5x2 |
3x3 |
16 (III ) |
||
|
|
|||||||||
|
0 3.5x |
2 |
3x |
16 (III ) |
|
|
0 0.5x |
2 |
1x |
2 (I ) |
|
|
3 |
|
|
|
|
3 |
|
Затем выполняют исключение неизвестного xk |
x2 |
из строк с k 1 ой |
||||||||
по n ую (здесь из 3-ей строки) по схеме: |
|
|
|
|
|
|
||||
4x1 3x2 |
0x3 |
10 |
(II) |
4x1 3x2 |
0x3 |
10 |
(II) |
|||
|
3.5x2 |
3x3 |
16 |
|
|
|
|
3x3 |
16 |
|
0 |
(III ) |
0 3.5x2 |
(III ) |
|||||||
|
0.5x2 |
1x3 |
2 |
(I ) (I ) - (-0.5/3.5) (III ) |
|
0x2 |
1.43x3 |
4.29 |
(I ) |
|
0 |
0 |
Этим завершается прямой ход метода исключения Гаусса.
Обратный ход (или обратная подстановка) состоит в вычислении xn x3 из последнего уравнения: xn x3 4.29/1.43 3, а затем его подстановки
в уравнения, расположенные |
выше, |
и вычислении |
сначала |
|
x2 (16 3 x3 ) /3.5 (16 3 3) /3.5 2 |
из |
2-го |
уравнения, а |
затем и |
x1 (10 3x2 0 x3 )/ 4 (10 3 2 0)/ 4 1 |
из 1-го уравнения. |
|
||
|
10 |
|
|
|