Горячее
Лучшее
Свежее
Подписки
Сообщества
Блоги
Эксперты
Войти
Забыли пароль?
или продолжите с
Создать аккаунт
Регистрируясь, я даю согласие на обработку данных и условия почтовых рассылок.
или
Восстановление пароля
Восстановление пароля
Получить код в Telegram
Войти с Яндекс ID Войти через VK ID
ПромокодыРаботаКурсыРекламаИгрыПополнение Steam
Пикабу Игры +1000 бесплатных онлайн игр Hit ball— аркадный шутер с элементами рогалика! Отбивай волны врагов, прокачивай способности и проходи уровни с ловушками и боссами!

Хитбол

Аркады, Казуальные, Для мальчиков

Играть

Топ прошлой недели

  • Oskanov Oskanov 9 постов
  • Animalrescueed Animalrescueed 46 постов
  • AlexKud AlexKud 33 поста
Посмотреть весь топ

Лучшие посты недели

Рассылка Пикабу: отправляем самые рейтинговые материалы за 7 дней 🔥

Нажимая «Подписаться», я даю согласие на обработку данных и условия почтовых рассылок.

Спасибо, что подписались!
Пожалуйста, проверьте почту 😊

Помощь Кодекс Пикабу Команда Пикабу Моб. приложение
Правила соцсети О рекомендациях О компании
Промокоды Биг Гик Промокоды Lamoda Промокоды МВидео Промокоды Яндекс Маркет Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня
0 просмотренных постов скрыто
8
bighouse.live
bighouse.live
3 года назад

Виртуальная ось⁠⁠

Добрый день. Сегодня хотелось бы рассказать про виртуальную ось в экселе :).

Для примера попробуем решить задачку поворота графика на 90°. Т.е. чтобы линии строились не вдоль оси Х, а вдоль Y. Чисто ради примера...

Для этого потребуется... внезапно... построить ещё один график, который нам и заменит ось Y.

Методика построения для двух линий (см.рисунок ниже):

1. Создаём два дополнительных столбца равных по величине исходным данным. Столбец Х3 с равными значениями меньше минимального значения (для левого расположения оси) исходных данных. Столбец Y3 - с нумерацией исходных данных.

2. Строим три точечных графика (иксы и игрики пометил в названиях столбцов). Точнее диаграмму с тремя точечными графиками на ней... Не отдельные графики.

3. Настраиваем оси (мин/макс), при этом минимум по оси Х должен равняться значению заданному в Х3 (для левого расположения оси). Убираем отображение подписей. Убираем/настраиваем сетку.

4. Для 3-го (виртуального) графика включаем отображение меток данных, отключаем отображение осей ХY, указываем данные из ячеек как подписи, указываем расположение меток слева .

5. Меняем размер зоны построения, чтобы метки влезали красиво.

6. Настраиваем вид виртуальной оси (третьего графика) - вид маркеров, цвет линии и т.д.

Если нужно подписи иметь справа, то Х3 больше максимального значения исходных данных, Хмакс = Х3 и расположение меток - справа.

Как видно - совсем не трудное решение значительно расширяет функционал экселя в плане отображений.

Я думаю что понятно, это только пример... Как вариант другого применения - отображение меток событий неделя/месяц/год/квартал/полугодие...


============

ПыСы я немного заработался - готовлюсь к сдаче экзамена в РосТехНадзор... Не до постов пока. Всё таки в сорок лет учиться труднее чем в 20ть. Печаль...

Показать полностью 2
[моё] Microsoft Excel Прост
1
93
bighouse.live
bighouse.live
3 года назад
MS, Libreoffice & Google docs

Весёлые маркеры графиков⁠⁠

Сегодня расскажу про простой способ разукрасить диаграммы, а именно заменить маркеры на произвольные рисунки.

Установка рисунков в качестве маркеров позволяет разнообразить внешний вид документации, сделав её нагляднее. Установка смайлов (© http://www.kolobok.us/ ) сделана в качестве примера (помните про Aiwan то? Или забыли...).

Для гармоничного отображения требуется проредить количество маркеров, в противном случае произойдёт наложение рисунков друг на друга. О прореживании писал ранее.

Заменить маркеры на рисунки, в данном случае они представлены смайлами, можно при помощи не сложного макроса


Sub Markers_Smiles()

ActiveSheet.ChartObjects("Диаграмма 1").Activate

For Each icell In [C2:C102]

ActiveChart.FullSeriesCollection(1).Points(icell.Row - 1).Select

' Убираю рамки вокруг маркеров

Selection.MarkerForegroundColorIndex = xlNone

' Установка типа маркера «Рисунок»

Selection.MarkerStyle = -4147

Selection.Format.Fill.UserPicture "D:\4.gif"

If icell.Value = 0 Then Selection.Format.Fill.UserPicture "D:\1.gif"

If icell.Value = 1 Then Selection.Format.Fill.UserPicture "D:\2.gif"

If icell.Value = 2 Then Selection.Format.Fill.UserPicture "D:\3.gif"

Next

End Sub


Где

[C2:C102] - столбец с признаками маркера. Число элементов равно числу данных (Х или Y). Может как заполняться вручную, так и быть расчётным (см.рисунок ниже).

D:\1.gif ... D:\4.gif - пути к рисункам.


Аналогично производится заполнение рисунками нескольких графиков на диаграмме

Прореживаем


Sub Прореживание_маркеров()

' Активируем диаграмму

ActiveSheet.ChartObjects("Диаграмма 1").Activate

' Перебор по всем графикам диаграммы

For k = 1 To ActiveChart.FullSeriesCollection.Count

' Удаляем все маркеры на линии

For i = 1 To ActiveChart.SeriesCollection(k).Points.Count

ActiveChart.FullSeriesCollection(k).Points(i).Select

Selection.MarkerStyle = -4142

Next i

' Выставляем маркеры с требуемым шагом.

For i = 1 To ActiveChart.SeriesCollection(k).Points.Count Step 4

ActiveChart.FullSeriesCollection(k).Points(i).Select

With Selection

.MarkerStyle = 8

.MarkerSize = 15

End With

Next i

Next k

End Sub


Проставляем рисунки


Public Sub color_graph()

ActiveSheet.ChartObjects("Диаграмма 1").Activate

For k = 1 To ActiveChart.FullSeriesCollection.Count ' Перебор по всем графикам

For Each icell In [C2:C102]

ActiveChart.FullSeriesCollection(k).Points(icell.Row - 1).Select

Selection.MarkerStyle = -4147

Selection.Format.Fill.UserPicture "D:\4.gif"

If icell.Value = 0 Then Selection.Format.Fill.UserPicture "D:\1.gif"

If icell.Value = 1 Then Selection.Format.Fill.UserPicture "D:\2.gif"

If icell.Value = 2 Then Selection.Format.Fill.UserPicture "D:\3.gif"

Next

Next k

End Sub


Аналогично разным графикам одной диаграммы можно присвоить уникальные маркеры

Sub Markers()

ActiveSheet.ChartObjects("Диаграмма 1").Activate

For i = 1 To ActiveChart.FullSeriesCollection.Count ' Перебор по всем графикам

ActiveChart.FullSeriesCollection(i).Select

Selection.MarkerForegroundColorIndex = xlNone

Selection.MarkerStyle = -4147

If i = 1 Then Selection.Format.Fill.UserPicture "D:\1.gif"

If i = 2 Then Selection.Format.Fill.UserPicture "D:\2.gif"

If i = 3 Then Selection.Format.Fill.UserPicture "D:\3.gif"

If i = 4 Then Selection.Format.Fill.UserPicture "D:\4.gif"

If i = 5 Then Selection.Format.Fill.UserPicture "D:\5.gif"

Next i

End Sub


Ну или просто разными штатными маркерами разные графики. Но в автоматическом режиме - очень сокращает время подготовки документации. Полезно при подготовке к печати в чёрно-белом варианте.

Sub Установка_разных_маркеров()

ActiveSheet.ChartObjects("Диаграмма 1").Activate

For i = 1 To ActiveChart.FullSeriesCollection.Count ' Перебор по всем графикам

ActiveChart.FullSeriesCollection(i).Select

Selection.Format.Line.ForeColor.RGB = RGB(0, 0, 0) ' Цвета линий и маркера

Selection.Format.Line.Weight = 0.75 ' Установка толщины линии

Selection.MarkerStyle = i ' Установка типа маркера

Selection.MarkerSize = 4 ' Установка размера маркера

Selection.Format.Fill.ForeColor.RGB = RGB(255, 255, 255) ' Установка заливки маркера

Next i

End Sub


Можно ли это сделать без макросов? Несомненно. Долго и нудно кликать кнопочки.

Но как по мне - проще скопировать и немного поправить код простого макроса. А в остальном - ваш выбор.

Показать полностью 5
[моё] Microsoft Excel Vba Прост Длиннопост
4
203
bighouse.live
bighouse.live
3 года назад
MS, Libreoffice & Google docs

Excel триальный⁠⁠

Немного отвлечённый пост о защите своей работы.

Итак, общеизвестны способы закрытия информации в Excel, а именно:

1. Защита листа/книги

Выбираем разрешения/допуски, вводим пароль, сохраняем файл.

Дополнительно для каждой ячейки можно указать защищается ли она или нет. По умолчанию - защищается.

2. Защита кода

Точно так же вводим пароль (с повторением), ок, сохраняем.


Но все эти способы не более чем игрушки, и вскрываются совершенно не сложно при наличии некоторых минимальных навыков и особенно при сохранении в *.xlsm (файл с поддержкой макросов). Сохраняйте в *.xlsb (двоичный код), если хотите хоть немного защитить свою работу.

Впрочем защита листа, даже без задания пароля, очень полезная вещь позволяющая ограничить вероятность порчи документа. Например если оставить без защиты (доступными для редактирования) только ячейки с исходными данными, то сам расчёт шаловливыми ручками испорчен не будет. Довольно часто пользуюсь...


Каким же образом можно ещё затруднить использование вашей работы, кроме как не давать её?

Ну для начала надо определиться что защищаем. Если это просто текст, и вы его кому то отдали, то забудьте о защите - он общедоступен. Но документ Excel это, прежде всего расчёты. Своей масштабируемостью они и ценны - при изменении исходных данных пересчёт произойдёт автоматически. 

Этим можно воспользоваться выполнив передачу результатов расчёта в виде статических таблиц. Да, можно распечатать/сохранить в pdf,  или банальным Ctrl+А /  Ctrl+C / Ctrl+V /только значения/. А можно просто воспользоваться простым макросом:


' Замена всех формул на листе в значения

Sub Form_2_Dan()

Dim a As Integer

' Запрашиваем подтверждение

a = MsgBox("Внимание!" & _

Chr(10) & "Вы точно хотите заменить все формулы на листе на значения?" & _

Chr(10) & "Это необратимо!", _

52, "Замена формул на значения.")

' Если OK, то замену производим

If a = 6 Then

ActiveSheet.UsedRange.Value = ActiveSheet.UsedRange.Value

End If

End Sub


Расположение макроса - модуль.

Макрос сохраняется в личный набор/надстройку и кнопка запуска выводится на панель.

Внимание! Действие макроса необратимо!


Можно сделать "триальным" расчёт разместив в модулях листов вот такого вида макрос.


Private Sub Worksheet_Activate()

Application.ScreenUpdating = False

If Date >= #10/6/2022# Then ActiveSheet.UsedRange.Value = ActiveSheet.UsedRange.Value

Application.ScreenUpdating = True

End Sub


Т.е. после 10.06.2022 все расчёты с листа исчезнут... А цифры останутся.

Можно заменить проверку на заполнение ячейки, например проверить что в определённой ячейке записан автор труда "Вася Пупкин". :) При смене которого всё превратится в набор цифр..

Естественно доступ к макросам должен быть закрыт/запаролен.


Ещё вариант - ввод пароля на саму книгу:


Private Sub Workbook_Open()

Dim i&, n&, P As Variant

Application.ScreenUpdating = False

n = 2

If Date >= #1/2/2022# Then

For i = 1 To Sheets.Count

Sheets(i).Activate

Sheets(i).Protect "1234"

Next

1:

P = InputBox("Время использования книги истекло, для продолжения введите пароль", "ВВОД ПАРОЛЯ")

If P = "°0176" Then

For i = 1 To Sheets.Count

Sheets(i).Activate

Sheets(i).Unprotect "1234"

Next

Else

If n = 0 Then

Application.DisplayAlerts = False

ThisWorkbook.Close

Application.DisplayAlerts = True

Else

MsgBox "Пароль не верный, у вас еще " & n & " попытки"

n = n - 1

End If

GoTo 1

End If

End If

Application.ScreenUpdating = True

End Sub


Расположение макроса - "Эта книга".


#1/2/2022# - дата с которой будет запрашиваться пароль

"°0176" – правильный пароль

И при открытии файл будет встречать весёлым окошком:

Естественно можно открыть файл без выполнения макросов, но если расчёт в экселе построен на использовании макросов, то цель достигнута - расчёт производиться не будет.


И да, это всё игрушки - серьёзные дяденьки с тётеньками при необходимости поломают сие поделия, и узнают как вы определяли дискриминант...  (0_о). Даже если Вы применили обфускацию кода или перенос кода в dll.

Показать полностью 3
[моё] Microsoft Excel Vba Прост Длиннопост
15
TechnoGAME
TechnoGAME
3 года назад

Ответ на пост «Хочу на море »⁠⁠

Хотеть не вредно.

[моё] Море Отпуск Топ Прост Текст
8
12
bighouse.live
bighouse.live
3 года назад

Это достижение! Я в отпуске⁠⁠

Ну вот, 10 лет в школе, 6 в институте, 4 в аспирантуре, более 15 лет полевой практики, начальник отдела паротурбинных установок центрального ремонтно–механического завода, и вот свершилось - доверили лопату, и выпустили на субботник :). Вообще полезное действие - позитивно поработали.

Это достижение! Я в отпуске

И да, с завтрашнего дня в отпуске. Планов - громадьё. Починить ОДА-102СВР, таки освоить "PowerQuery в Excel и PowerBi: сбор, объединение и преобразование данных" Г.Равив. А то купил и никак руки не дойдут сесть за неё. Ну и парочку постов на Пикабу, раз обещал.

Показать полностью 1
[моё] Прост Субботник Отпуск
9
70
bighouse.live
bighouse.live
3 года назад
MS, Libreoffice & Google docs
Серия Оцифровка

Excel. Долгая дорога оцифровки. Часть 4.  Макрос по созданию макросов апроксимации простых графиков полиномом⁠⁠

"Позабыты хлопоты, остановлен бег, Вкалывают роботы, счастлив человек!"(с)ПЭ

В этом посте я хотел бы показать, что ничего сложного в создании макроса, который бы выполнял рутинную работу по созданию макросов нет.

Всё базируется на трёх китах:

1. Унификация.

2. Результатом действия макроса может являться текст;

3. В текстовых переменных можно использовать спец символы:

3.1. Знак возврата каретки. vbCr она же символ Chr(13);

3.2. Знак перевода строки. vbLf она же символ Chr(10);

3.3. Символ объёдинения &.

Ну а теперь пройдём все шаги вместе.


В прошлом посте я говорил про макрос расчёта на основании построения тренда.


====

' Апроксимация полиномом для всего массива исходных данных

' В подпрограмму передаются все заданные точки и апроксимация ведётся по всем точкам!

' Данные из листа Excel

Public Function polinomEx_all(xVal As Range, yVal As Range, x As Single, Optional stepen As Long = 2) As Variant

Dim i As Integer

' Проверка требования "число элементов массива на 1 больше чем степень полинома"

If xVal.Count < stepen + 1 Then

stepen = xVal.Count - 1

End If

polinomEx_all = 0#


Select Case stepen


Case 1 ' Уравнение а·х+b

For i = 1 To stepen + 1

polinomEx_all = polinomEx_all + (x ^ (stepen + 1 - i)) * Application.Index(WorksheetFunction.LinEst(yVal, xVal, True, True), 1, i)

Next i


Case 2 ' Уравнение а·х^2+b·x+c

For i = 1 To stepen + 1

polinomEx_all = polinomEx_all + _

(x ^ (stepen + 1 - i)) * Application.Index(WorksheetFunction.LinEst(yVal, Application.Power(xVal, Array(1, 2)), True, True), 1, i)

Next i


Case 3 ' Уравнение а·х^3+b·x^2+c·x+d

For i = 1 To stepen + 1

polinomEx_all = polinomEx_all + _

(x ^ (stepen + 1 - i)) * Application.Index(WorksheetFunction.LinEst(yVal, Application.Power(xVal, Array(1, 2, 3)), True, True), 1, i)

Next i


Case 4 ' Уравнение а·х^4+b·x^3+c·x^2+d·x+e

For i = 1 To stepen + 1

polinomEx_all = polinomEx_all + _

(x ^ (stepen + 1 - i)) * Application.Index(WorksheetFunction.LinEst(yVal, Application.Power(xVal, Array(1, 2, 3, 4)), True, True), 1, i)

Next i


Case 5 ' Уравнение а·х^5+b·x^4+c·x^3+d·x^2+e·x+f

For i = 1 To stepen + 1

polinomEx_all = polinomEx_all + _

(x ^ (stepen + 1 - i)) * Application.Index(WorksheetFunction.LinEst(yVal, Application.Power(xVal, Array(1, 2, 3, 4, 5)), True, True), 1, i)

Next i


Case 6 ' Уравнение а·х^6+b·x^5+c·x^4+d·x^3+e·x^2+f·x+g

For i = 1 To stepen + 1

polinomEx_all = polinomEx_all + _

(x ^ (stepen + 1 - i)) * Application.Index(WorksheetFunction.LinEst(yVal, Application.Power(xVal, Array(1, 2, 3, 4, 5, 6)), True, True), 1, i)

Next i


Case 7 ' Уравнение а·х^7+b·x^6+c·x^5+d·x^4+e·x^3+f·x^2+g·x+h

For i = 1 To stepen + 1

polinomEx_all = polinomEx_all + _

(x ^ (stepen + 1 - i)) * Application.Index(WorksheetFunction.LinEst(yVal, Application.Power(xVal, Array(1, 2, 3, 4, 5, 6, 7)), True, True), 1, i)

Next i

Case Else

End Select

End Function

====

Как видно - ничего сложного в этом макросе нет. В соответствии с заявленной степенью полинома происходит перемножение заданного Х в соответствующей степени на соответствующий коэффициент полинома. Коэф-ты вычисляются точно так же как вычислялись на листе экселя.

Т.е.

WorksheetFunction.LinEst(yVal, Application.Power(xVal, Array(1, 2, 3, 4)), True, True)

полностью совпадает с

ЛИНЕЙН(Y; X{1;2;3;4}; True; True)


Ну а теперь просто заменим расчёт на составление текстовой переменной

=====

' Апроксимация полиномом для всего массива исходных данных

' В подпрограмму передаются все заданные точки и апроксимация ведётся по всем точкам!

' Данные из листа Excel

' Результат работы программы - текст (уравнение полинома)

Public Function polinomExStr(ByVal xVal As Range, ByVal yVal As Range, Optional stepen As Long = 2) As Variant

' Проверка требования "число элементов массива на 1 больше чем степень полинома"

Dim i As Integer

If xVal.Count < stepen + 1 Then

stepen = xVal.Count - 1

End If

polinomExStr = ""


Select Case stepen


Case 1 ' Уравнение а·x+c

For i = 1 To 2

polinomExStr = polinomExStr & " + X ^ " & (2 - i) & " * " _

& Format(Application.Index(WorksheetFunction.LinEst(yVal, Application.Power(xVal, Array(1)), True, True), 1, i), "0.###E+")

Next i


Case 2 ' Уравнение а·х^2+b·x+c

For i = 1 To 3

polinomExStr = polinomExStr & " + X ^ " & (3 - i) & " * " _

& Format(Application.Index(WorksheetFunction.LinEst(yVal, Application.Power(xVal, Array(1, 2)), True, True), 1, i), "0.###E+")

Next i


Case 3 ' Уравнение а·х^3+b·x^2+c·x+d

For i = 1 To 4

polinomExStr = polinomExStr & " + X ^ " & (4 - i) & " * " _

& Format(Application.Index(WorksheetFunction.LinEst(yVal, Application.Power(xVal, Array(1, 2, 3)), True, True), 1, i), "0.###E+")

Next i


Case 4 ' Уравнение а·х^4+b·x^3+c·x^2+d·x+e

For i = 1 To 5

polinomExStr = polinomExStr & " + X ^ " & (5 - i) & " * " _

& Format(Application.Index(WorksheetFunction.LinEst(yVal, Application.Power(xVal, Array(1, 2, 3, 4)), True, True), 1, i), "0.###E+")

Next i


Case 5 ' Уравнение а·х^5+b·x^4+c·x^3+d·x^2+e·x+f

For i = 1 To 6

polinomExStr = polinomExStr & " + X ^ " & (6 - i) & " * " _

& Format(Application.Index(WorksheetFunction.LinEst(yVal, Application.Power(xVal, Array(1, 2, 3, 4, 5)), True, True), 1, i), "0.###E+")

Next i


Case 6 ' Уравнение а·х^6+b·x^5+c·x^4+d·x^3+e·x^2+f·x+g

For i = 1 To 7

polinomExStr = polinomExStr & " + X ^ " & (7 - i) & " * " _

& Format(Application.Index(WorksheetFunction.LinEst(yVal, Application.Power(xVal, Array(1, 2, 3, 4, 5, 6)), True, True), 1, i), "0.###E+")

Next i


Case 7 ' Уравнение а·х^7+b·x^6+c·x^5+d·x^4+e·x^3+f·x^2+g·x+h

For i = 1 To 8

polinomExStr = polinomExStr & " + X ^ " & (8 - i) & " * " _

& Format(Application.Index(WorksheetFunction.LinEst(yVal, Application.Power(xVal, Array(1, 2, 3, 4, 5, 6, 7)), True, True), 1, i), "0.###E+")

Next i

Case Else

End Select

End Function

=====


Ну или немного в другом виде с учётом ряда особенностей и модификаций

=====

' Программа формирования текста макроса для функции одного уравнения

Public Function fun_macros_Y(xVal As Range, yVal As Range, PolyStep As Long, _

Optional Name_f As String = "Nomogramma", _

Optional Opisanie As String = " Уравнение ", _

Optional NameX As String = "Xisk") As Variant

Dim j As Long

Dim N As Long

Dim k As Long

Dim stepen As Long

Dim xn() As Double ' заявляем массив X

Dim yn() As Double ' заявляем массив Y

Dim c() As Double ' заявляем массив c - коэффециенты уравнения полинома

fun_macros_Y = "" & Chr(10) & "' " & Opisanie & Chr(10)

fun_macros_Y = fun_macros_Y & "Public Function " & Name_f & "(ByRef " & NameX & " As Single) As Variant" & Chr(10)

Dim Nna4 As Long 'Номер начала диапазона.

Dim Nkon As Long 'Номер конца диапазона.

Nna4 = 1

Nkon = xVal.Count

' Проверяем на соответствие число элементов участка степени полинома

If (Nkon - Nna4) < PolyStep Then

stepen = (Nkon - Nna4)

Else

stepen = PolyStep

End If

' Заполняем матрицы участка

ReDim xn(1 To (Nkon - Nna4 + 1), 1 To stepen)

ReDim yn(1 To (Nkon - Nna4 + 1), 1 To 1)

ReDim c(1 To stepen + 1) As Double

For j = 1 To (Nkon - Nna4 + 1)

xn(j, 1) = xVal.Rows(j + Nna4 - 1)

For N = 2 To stepen

xn(j, N) = xn(j, 1) ^ N

Next N

yn(j, 1) = yVal.Rows(j + Nna4 - 1)

Next j

' Делаем расчёт и вывод.

fun_macros_Y = fun_macros_Y & Name_f & " = "

For k = 1 To stepen + 1 Step 1

c(k) = Format(Application.Index(WorksheetFunction.LinEst(yn, xn, True, True), 1, k), "0.####E+")


If c(k) >= 0 And k > 1 Then

fun_macros_Y = fun_macros_Y & " + " & c(k)

Else

fun_macros_Y = fun_macros_Y & c(k)

End If


If (stepen + 1 - k) > 0 Then

fun_macros_Y = fun_macros_Y & " * " & NameX & " ^ " & (stepen + 1 - k) & " "

End If

Next k


fun_macros_Y = fun_macros_Y & Chr(10) & "End Function" & Chr(10)

End Function

=====


Макрос ждёт в качестве вводных данных:

xVal - столбец известных Х

yVal - столбец известных Y

PolyStep - желаемую степень уравнения. Если точек будет меньше чем требуется для степени - на уменьшится

Name_f - название получаемого макроса. Опционально. Если не задать будет Nomogramma

Opisanie - описание получаемого макроса. Опционально. Если не задать будет Уравнение

NameX - название/имя аргумента. Опционально. Если не задать будет Xisk


Вызов макроса:

=ПОДСТАВИТЬ(fun_macros_Y(X; Y; 3; "fun_пример"; "Пример создания макроса"; "Go");",";".")


=ПОДСТАВИТЬ( ;",";".") требуется для замены запятых на точки. Иначе будет казус - VBA в качестве разделителя целой и дробной части использует точку, а в текстом виде (по крайней мере в рус.экселе) разделитель запятая.

Обратите внимание, что

"fun_пример"; "Пример создания макроса"; "Go" - текстовые, т.е. заключаются в кавычки

"fun_пример";  "Go" - должны соответствовать требованиям к переменным. Т.е. не должны содержать пробелов, не должны совпадать с имеющимися переменными или названиями ячеек/диапазонов.


Результатом выполнения макроса будет (поставил 3-ю степень чтобы результат влез в окно поста):

"

' Пример создания простого макроса

Public Function fun_Wтф(ByRef Go As Single) As Variant

fun_Wтф = 0.00000056401 * Go ^ 3 -0.001952 * Go ^ 2 + 1.3842 * Go ^ 1 + 25.341

End Function

"

Останется скопировать данный текст в модуль VBA и удалить двойные кавычки в начале и конце текстовки.


Если есть желание повысить количество знаков коэффициентов - правим формат "0.####E+"


Для ускорения работы у меня собраны листы/шаблоны позволяющие не лезть в заполнение вызова макросов.

Вызов макроса для данного случая у меня выглядит так (в Е9):

=ПОДСТАВИТЬ(fun_macros_Y(B3:ДВССЫЛ("B"&E4);C3:ДВССЫЛ("C"&E4);M7;E7;G5;G7);",";".")

Как заполнены дополнительные столбцы А, D и ячейки Е4 и т.д. видно на скрине.

Столбец А - контроль верности снятия данных (по возрастанию Х).

Столбец D - подсчёт снятых точек.

В итоге выполнение/изготовление макроса для меня сводится в вставке исходных данных начиная с ячейки В3, и затем жёлтых полей ввода описания, ввода названия новой функции и аргумента, выбора степени. Т.е. занимает не более минуты.


Для наблюдательных - присутствующие в макросе Dim Nna4 As Long 'Номер начала диапазона.

Dim Nkon As Long 'Номер конца диапазона.

намекают на то, что после небольшой модификации данный макрос можно использовать для более сложных диаграмм. Но об этом позднее... Думаю что через неделю в лучшем случае.


Для продвинутых - да, можно обойтись без доп.столбцов А и D, да и E4 лишнее. И то и другое можно реализовать в макросе, но...но данный лист был так сформирован на основании удобства для меня - могу оперативно проверить правильность и полноту вставки исходных данных, отсутствие сбоев "снятия" точек с картинки при массовой оцифровке. И вообще - "работает? Стабильно? Без сбоев? Не трожь!" (с)Анекдот. Вам ничто не мешает сделать иначе.


=========

dixi


Краткий план:

Теория вкратце [ Часть 1. ]

Забираем данные с листа. [ Часть 2. ]

Апроксимация простых графиков полиномом средствами Excel [ Часть 3.]

Макрос по созданию макросов апроксимации простых графиков полиномом [ Часть 4.] Этот пост

Апроксимация графиков двух аргументов полиномом [ Часть 5.]

Кусочная интерполяция простых графиков [ Часть 6.]

Показать полностью 2
[моё] Microsoft Excel Vba Прост Длиннопост
8
46
bighouse.live
bighouse.live
3 года назад
MS, Libreoffice & Google docs
Серия Оцифровка

Excel. Долгая дорога оцифровки. Часть 3. Апроксимация простых графиков полиномом средствами Excel⁠⁠

Итак, мы имеем набор точек XY и нам требуется определить значение между заданными (опорными) точками. Начнём с самого простого варианта - набор точек позволяет найти уравнение полиномиального вида, которое с достаточной нам точностью описывает поведение функции с учётом имеющихся точек. Это будет в 90% апроксимация т.к. помним про погрешности связанные со снятием точек. Т.е. значения полученные по данной функции будут отличаться от заданных изначально. Кроме вариантов при степени полинома на 1 меньше количества точек (например полином 5-й степени, а известных точек 6-ть).

Стоит учитывать, что описанный ниже способ подходит только в ограниченном количестве случаев:

- требует заказчик;

- зависимость явно полиномиальная.

Итак, в общем случае всё сводится к пяти шагам:

1. По имеющимся данным построить точечный график.

2. По построенным точкам выполнить построение линии тренда.

3. Подобрать степень полиномиальной зависимости таким образом, чтобы внешний вид (прохождение около/через заданные точки) соответствовал изначальному графику (тот что был на картинке). Проверить, возможно полином не лучший вариант.

4. Отобразить уравнение линии тренда на диаграмме и, если зависимость полиномиальная, становить формат чисел "Экспоненциальный" Число знаков - не менее 3х знаков.

5. Скопировать полученное уравнение и использовать в дальнейшем.

Есть ли способы без построения? Естественно есть (о них чуть подальше), но не видя как расположена линия тренда можно нарваться на неприятности.

Ещё одно заблуждение - "чем больше степень полинома, тем точнее". К сожалению, если по оси Х значения в десятках тысяч, а по оси Y в единицах фактически не реально найти полином выше 5-й степени. Точнее определить с достаточной достоверностью его коэффициенты (просто не хватает 15-ти знаков).

Определение коэффициентов полинома.

Как видно на скриншоте выше извлечение коэффициентов полинома происходит совсем не сложно.

=ИНДЕКС(ЛИНЕЙН(F4:F13;E4:E13^{1;2;3;4;5;6});1;7)

где {1;2;3;4;5;6} - степень полинома, 7 - порядковый номер коэффициента.

И об этом написано в многих местах. Но вот то что не написано - извлечённые таким способом иногда не совсем соответствуют коэф-ам уравнения на диаграмме, а иногда совсем не соответствуют.

Это внутренняя математика Excel и  может быть вызвано целым рядом причин. Основные:

- Значительный разрыв исходных данных. Например есть несколько сот снятых точек от 0 до 10, затем отсутствие снятых точек от 10 до 20, затем несколько сот точек с 20 до 50.

- Значительные степени чисел (как на скрине выше).

Выходом из данной ситуации является следующий макрос-костыль который забирает данные из указанного диапазона ( в примере - "B2:B6"  Данные Х  и "C2:C6" -  Данные Y), строит график, на графике строит линию тренда с заявленной степенью (в примере вторая - Order = 2), копирует строку уравнения, распарсивает её и выкидывает в столбец (  в примере - начиная с ячейки E2 и вниз) коэффициенты полин.уравнения. Построенный график удаляется...


Sub Polynomial()

Dim rX As Range

Dim rY As Range

Dim rOut As Range

Dim dataLabelText As String

Dim coefficients As Variant

Set rX = ActiveSheet.Range("B2:B6") ' Данные Х

Set rY = ActiveSheet.Range("C2:C6") ' Данные Y

Set rOut = ActiveSheet.Range("E2") ' Место выгрузки коэф-в

dataLabelText = Извлечение_Полинома(rX, rY)

coefficients = Извлечение_коэффициентов(dataLabelText)

With rOut.Resize(UBound(coefficients, 1) + 1, UBound(coefficients, 2))

'назначаем формат для избежания ошибок при вставке получившихся формул

.NumberFormat = "#.####E+00"

.Value = coefficients

End WithEnd Sub


Private Function Извлечение_коэффициентов(dataLabelText As String) As Variant

Dim i As Integer

Dim rez() As Variant, txt As Variant

txt = Split(dataLabelText, "x")

ReDim rez(LBound(txt) To UBound(txt), 1 To 2)

For i = LBound(txt) To UBound(txt)

txt(i) = Right(txt(i), IIf(i = LBound(txt), (Len(txt(i)) - 2), (Len(txt(i)) - 1)))

rez(i, 1) = i: rez(i, 2) = txt(i)

Next i

Извлечение_коэффициентов = rez

End Function


Function Извлечение_Полинома(rX As Range, rY As Range) As String

Dim MyChart As Chart

Dim text As String

Dim dt As Date

Set MyChart = ActiveSheet.Shapes.AddChart2(, , , , 450, 300).Chart

With MyChart

.SeriesCollection.NewSeries

.SeriesCollection(1).XValues = rX

.SeriesCollection(1).Values = rY

.ChartType = xlXYScatter

.FullSeriesCollection(1).Trendlines.Add

With .FullSeriesCollection(1).Trendlines(1)

.Type = xlPolynomial

.Order = 2 ' Указываем степень полинома

.DisplayEquation = True

.DataLabel.NumberFormat = "#.####E+00"

dt = Now

DoEvents ' Задержка. См. ниже

DoEvents ' Задержка. См. ниже

Do

If .DataLabel.text <> "" Then Exit Do

If dt < Now - TimeSerial(0, 1, 0) Then Exit Do

For i = 1 To 100: DoEvents: Next

Loop

text = .DataLabel.text

End With

End With

Извлечение_Полинома = text

MyChart.Parent.Delete

End Function


Т.е. делает то, что можно сделать и руками с наглядным выбором вида апроксимации.


Быстрое определение искомого Y по заданному X.

Если Вы уверены в своём глазомере, не боитесь подводных камней и хотите быстро получить значение, то можно воспользоваться вот таким макросом.

Сокращённый вид макроса за авторством БМВ расположен ниже. Расширенный частично на скрине выше. Он понадобится нам в следующем посте, когда будем делать макрос по созданию макросов ), и там будет представлен полностю.


Public Function polinomEx(xVal As Range, yVal As Range, X As Single, stepen As Integer)

Dim I As Integer

Dim Seria

Seria = Array(1, 2, 3, 4, 5, 6, 7)

If stepen > 7 Then stepen = 7

If xVal.Count < stepen + 1 Then stepen = xVal.Count - 1

polinomEx = 0#

ReDim Preserve Seria(stepen - 1)

For I = 1 To stepen + 1

polinomEx = polinomEx + _

(X ^ (stepen + 1 - I)) * _

Application.Index(WorksheetFunction.LinEst(yVal, _

IIf(stepen = 1, xVal, Application.Power(xVal, Seria)), _

True, True), 1, I)

Next I

End Function

Т.е. в функцию передаются столбцы исходных данных, значение Х, при котором требуется найти Y и степень полинома линии тренда.


И да, все заметили что посредством макроса есть возможность построить полином 7-й степени, тогда как линия тренда позволяет выполнять это только до 6-й?


Дальнейшее использование уравнения апроксимации.

Существует всего два подхода:

- Хранить исходные данные на листе. Или в виде таблицы, или в виде уравнения в ячейке.

- Хранить уравнение в виде макроса.


Первый подход удобен при разовом использовании. Если возможно неоднократное использование зависимости, или возможна её модификация, или зависимостей больше десятка - макрос предпочтительнее.


О том как делать макросы для простых графиков, в том числе и в автоматизированном режиме, расскажу в следующий раз.

===========

Краткий план:

Теория вкратце [ Часть 1. ]

Забираем данные с листа. [ Часть 2. ]

Апроксимация простых графиков полиномом средствами Excel [ Часть 3.] Этот пост

Макрос по созданию макросов апроксимации простых графиков полиномом [ Часть 4.]

Апроксимация графиков двух аргументов полиномом [ Часть 5.]

Кусочная интерполяция простых графиков [ Часть 6.]

Показать полностью 5
[моё] Microsoft Excel Vba Прост Длиннопост
1
72
bighouse.live
bighouse.live
3 года назад
MS, Libreoffice & Google docs
Серия Оцифровка

Excel. Долгая дорога оцифровки. Часть 2. Забираем данные с листа⁠⁠

Под оцифровкой графиков будем понимать получение интерполяционной/аппроксимирующей функции (макроса), при вводе данных в которую будет получено значение, соответствующее значению, полученному с использованием графического метода (линейка и карандаш) на бумажном варианте графика-рисунка.

Первым этапом оцифровки будет получение набора данных XY соответствующих имеющейся кривой.

Некоторые РД (документация заводов-изготовителей, НТД, ТЭХ, ТНХ и т.д) предоставляют функции/уравнения, соответствующие графикам/номограммам. Однако стоит знать, что иногда предоставленная функция может не соответствовать предоставленному графику и требует проверки.

До проведения "снятия" точек требуется обработать отсканированный (если он таковой) график. А именно:

- максимально уменьшить искажения типа "горб" или "рыбий глаз. Т.е. сделать все вертикальные и горизонтальные линии параллельными между собой соответственно.

- максимально сделать перпендикулярными вертикальную и горизонтальную оси.

Всё это выполняется или в специализированных программах типа того же FineRader, или в пэйнте. От того насколько подготовите файл будет зависеть как потом точки будут отображаться на графике в Excel, а там, как известно, всё строго перпендикулярно.


В далёком прошлом помню варианты "снятия" точек путём вставки картинки в автокад, простановки точек, их переписывания и пересчёта... Сейчас же при отсутствии функций-зависимостей следует воспользоваться программой Graph2Digit, GetData Graph Digitizer или аналогичной. GetData Graph Digitizer продаётся за денежку, но т.к. я начинал работать с ней, она установлена у меня на работе (а у нас нельзя самому ставить софт), то показывать буду на ней. Но тут скорее дело привычки, и пары удобств, которых не помню в Graph2Digit - типа возможности снятия точек с нескольких линий.

При этом автоматизированность снятия точек хоть и заявлена для обеих программ, но на деле ни одна программа с этим не справляется на реальных диаграммах - требуется идеальный вариант с чётким выделением линий графиков по цветам, отсутствием сеток и наличия бубна. Фактически для реальных графиков "снятие" точек производится в ручном режиме.

Для желающих - выбираем язык программы.

1. Установить оси. Потребуется установить точки минимального Х, максимального Х, минимального У, максимального У. При этом, как видно на скриншоте выше, достаточно установить точки там, где заведомо известны значения. Например максимальный Х задан как 400, хотя график продолжается и далее - значение по осям будут пересчитаны соответственно.

2. Ручная простановка точек. В ручном режиме наводится на место снятия точки, при этом в увеличенном виде это место отображается справа в нижнем углу, и ЛКМ фиксируем точку. Все снятые точки отображаются в таблице справа.

3. Копирование снятых точек в буфер обмена. В дальнейшем "снятые" точки копируются в лист Excel, и с ними производятся различные манипуляции.



Это был описаны основные действия при ручном снятии.

Основные вопросы:

Насколько часто требуется производить "снятие" точек? Вопрос сложный... Но из опыта - линия, что связывает две проставленные точки, в идеале должна находиться внутри линии графика.

Что делать, если был не верно указан диапазон (например вместо Хмакс=1000 записали Хмакс=100)? Ничего страшного. Точки заново расставлять вдоль линии не надо, достаточно зайти в "Текущее состояние" - "Параметры" и задать правильное параметров осей.

Несколько советов:

- сохранять поле снятых точек. т.е. файл *.gdw. В дальнейшем, если обнаружится не верное отображение точек, легко проверить правильность указания осей. Дело в том, что если график один, то точки снимаются внимательно, и аккуратно. А когда ставится на поток, по 50 графиков в час, то бывают и плюхи...

- выставлять следующие настройки (в дальнейшем облегчат автоматическое получение макросов):

- немного забегая вперёд (постов эдак на 4). снятие точек производить от меньшего Х к большему. При наличии диаграммы зависимости от двух аргументов типаY(X1, X2) начиная с графика меньшего Х2.Т.е. см.диаграмму внизу - имеется зависимость qт(Nт,Qт). Снятие точек начинаем с Qт=0, Nт = 40... 120, затем с Qт=20, Nт = 40... 120 и т.д. С обязательным условием - каждая следующая линия должна начинаться с Х меньшего, чем закончилась предыдущая... Может немного сумбурно, но если понятней по видео, то вот - https://youtu.be/AXnTdHlmn34

- Нужно помнить, что погрешность оцифровки составляет толщину линии, и для вертикальных участков кривых может достигать 2%. Дополнительная погрешность вызывается искривлением графика при печати/сканировании. Поэтому точки, полученные в результате такого снятия можно, и подчас нужно, редактировать. Например, если Вы точно знаете что при Х=10 Y должен ровняться 20, а по снятым данным выходит 19.95, то или производится правка данной точки (заменяется на 20), или все точки поднимаются на 0,05 (+0,05).

При этом точность определения значений с помощью линейки и карандаша заведомо ниже, чем при использовании интерполированных кривых.

===========

Краткий план:

Теория вкратце [ Часть 1. ]

Забираем данные с листа. [ Часть 2. ] Этот пост

Апроксимация простых графиков полиномом средствами Excel [ Часть 3.]

Макрос по созданию макросов апроксимации  простых графиков полиномом [ Часть 4.]

Апроксимация графиков двух аргументов полиномом [ Часть 5.]

Кусочная интерполяция простых графиков  [ Часть 6.]

....

Показать полностью 4
[моё] Microsoft Excel Vba Прост Длиннопост
0
Посты не найдены
О нас
О Пикабу Контакты Реклама Сообщить об ошибке Сообщить о нарушении законодательства Отзывы и предложения Новости Пикабу Мобильное приложение RSS
Информация
Помощь Кодекс Пикабу Команда Пикабу Конфиденциальность Правила соцсети О рекомендациях О компании
Наши проекты
Блоги Работа Промокоды Игры Курсы
Партнёры
Промокоды Биг Гик Промокоды Lamoda Промокоды Мвидео Промокоды Яндекс Маркет Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня
На информационном ресурсе Pikabu.ru применяются рекомендательные технологии