Старый 22.08.2026, 05:03   #1
Les
Собеседник
 
Регистрация: 08.12.2018
Сообщения: 318
Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000
По умолчанию Превращаем Excel в астропроцессор

Здравствуйте!
Вот, хочу поделиться, сделано с помощью Ai, сам бы я не осилил, поскольку ни разу не программист.
Les вне форума   Ответить с цитированием
Старый 22.08.2026, 05:04   #2
Les
Собеседник
 
Регистрация: 08.12.2018
Сообщения: 318
Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000
По умолчанию

Построить классическую круглую натальную карту в Excel стандартными методами напрямую невозможно, так как графический движок Excel (диаграммы) жестко привязан к декартовой системе координат (сетка X и Y), гистограммам или биржевым графикам.
Однако, используя данные из таблиц и встроенный язык VBA, решить эту задачу можно.
VBA будет работать как графический редактор. Вместо построения диаграммы макрос будет буквально рисовать карту на листе Excel с помощью векторных фигур (ActiveSheet.Shapes.AddShape и AddLine).

Перед запуском кода убедитесь, что ваш рабочий лист выглядит следующим образом:

1. Столбец А: Двухбуквенное название планеты (например, SU, MO, ME, VE, MA).
2. Столбец B: Координата в десятичных градусах от 0 до 360 (например, 45,25, 120,5,).
3. Данные начинаются со строки 2 (строка 1 — для заголовков).

## Код макроса VBA
Чтобы вставить код: нажмите Alt + F11, выберите Insert -> Module, вставьте текст ниже и нажмите F5 для запуска.

Код:
Sub DrawAstrologyChart_Final() Dim ws As Worksheet Set ws = ActiveSheet ' 1. Очистка старых рисунков на листе Dim shp As Shape For Each shp In ws.Shapes shp.Delete Next shp ' 2. Геометрические настройки карты Dim centerX As Double, centerY As Double Dim rOuter As Double, rZodiacInner As Double, rPlanetCircle As Double Dim rTextSigns As Double, rTextPlanets As Double centerX = 400 centerY = 260 rOuter = 210 ' 1-й круг: Самая внешняя граница карты rZodiacInner = 175 ' 2-й круг: Внутренняя граница Зодиака rPlanetCircle = 135 ' 3-й круг: Линия положения планет rTextSigns = 192.5 ' Исправлено: только число rTextPlanets = 155# ' Исправлено: только число Dim pi As Double pi = 3.14159265358979 ' Латинские сокращения знаков зодиака Dim signs(0 To 11) As String signs(0) = "AR": signs(1) = "TA": signs(2) = "GE": signs(3) = "CN" signs(4) = "LE": signs(5) = "VI": signs(6) = "LI": signs(7) = "SC" signs(8) = "SG": signs(9) = "CP": signs(10) = "AQ": signs(11) = "PI" ' 3. Рисуем три каркасных круга ws.Shapes.AddShape(msoShapeOval, centerX - rOuter, centerY - rOuter, rOuter * 2, rOuter * 2).Fill.Transparency = 1 ws.Shapes.AddShape(msoShapeOval, centerX - rZodiacInner, centerY - rZodiacInner, rZodiacInner * 2, rZodiacInner * 2).Fill.Transparency = 1 ws.Shapes.AddShape(msoShapeOval, centerX - rPlanetCircle, centerY - rPlanetCircle, rPlanetCircle * 2, rPlanetCircle * 2).Fill.Transparency = 1 ' 4. Рисуем сетку 12 знаков зодиака Dim i As Integer Dim angleRad As Double, midAngleRad As Double Dim x1 As Double, y1 As Double, x2 As Double, y2 As Double Dim sX As Double, sY As Double Dim signBox As Shape Dim signLine As Shape For i = 0 To 11 angleRad = (i * 30) * pi / 180 x1 = centerX - rZodiacInner * Cos(angleRad) y1 = centerY + rZodiacInner * Sin(angleRad) x2 = centerX - rOuter * Cos(angleRad) y2 = centerY + rOuter * Sin(angleRad) Set signLine = ws.Shapes.AddLine(x1, y1, x2, y2) signLine.Line.ForeColor.RGB = RGB(160, 160, 160) midAngleRad = (i * 30 + 15) * pi / 180 sX = centerX - rTextSigns * Cos(midAngleRad) sY = centerY + rTextSigns * Sin(midAngleRad) Set signBox = ws.Shapes.AddTextbox(msoTextOrientationHorizontal, sX - 12, sY - 10, 24, 20) With signBox .TextFrame.Characters.Text = signs(i) .TextFrame.Characters.Font.Size = 9 .TextFrame.Characters.Font.Bold = True .TextFrame.HorizontalAlignment = xlHAlignCenter .TextFrame.VerticalAlignment = xlVAlignCenter .TextFrame.MarginLeft = 0 .TextFrame.MarginRight = 0 .TextFrame.MarginTop = 0 .TextFrame.MarginBottom = 0 .Line.Visible = msoFalse .Fill.Visible = msoFalse End With Next i ' 5. Считывание планет из таблицы Dim lastRow As Long Dim r As Long lastRow = ws.Cells(ws.Rows.count, "A").End(xlUp).Row If lastRow < 2 Then Exit Sub Dim count As Long count = lastRow - 1 ReDim pNames(1 To count) As String ReDim pLongs(1 To count) As Double ReDim pVisualLongs(1 To count) As Double Dim idx As Long idx = 1 For r = 2 To lastRow If ws.Cells(r, 1).Value <> "" Then pNames(idx) = ws.Cells(r, 1).Value pLongs(idx) = Val(ws.Cells(r, 2).Value) pVisualLongs(idx) = pLongs(idx) idx = idx + 1 End If Next r count = idx - 1 ' Сортировка планет (пузырьковый метод) Dim j As Long, tempLong As Double, tempVis As Double, tempName As String For i = 1 To count - 1 For j = i + 1 To count If pVisualLongs(i) > pVisualLongs(j) Then tempLong = pLongs(i): pLongs(i) = pLongs(j): pLongs(j) = tempLong tempVis = pVisualLongs(i): pVisualLongs(i) = pVisualLongs(j): pVisualLongs(j) = tempVis tempName = pNames(i): pNames(i) = pNames(j): pNames(j) = tempName End If Next j Next i ' Радвижка близких надписей Dim minDistance As Double minDistance = 6.5 Dim passes As Integer For passes = 1 To 5 For i = 1 To count Dim nextIdx As Long If i = count Then nextIdx = 1 Else nextIdx = i + 1 Dim diff As Double diff = pVisualLongs(nextIdx) - pVisualLongs(i) If diff < 0 Then diff = diff + 360 If diff < minDistance Then pVisualLongs(i) = pVisualLongs(i) - (minDistance - diff) / 2 pVisualLongs(nextIdx) = pVisualLongs(nextIdx) + (minDistance - diff) / 2 If pVisualLongs(i) < 0 Then pVisualLongs(i) = pVisualLongs(i) + 360 If pVisualLongs(nextIdx) >= 360 Then pVisualLongs(nextIdx) = pVisualLongs(nextIdx) - 360 End If Next i Next passes ' 6. Отрисовка планет Dim pX As Double, pY As Double Dim markerX As Double, markerY As Double Dim txtBox As Shape For i = 1 To count angleRad = pLongs(i) * pi / 180 markerX = centerX - rPlanetCircle * Cos(angleRad) markerY = centerY + rPlanetCircle * Sin(angleRad) ws.Shapes.AddShape(msoShapeOval, markerX - 2.5, markerY - 2.5, 5, 5).Fill.ForeColor.RGB = RGB(255, 0, 0) Dim visAngleRad As Double visAngleRad = pVisualLongs(i) * pi / 180 pX = centerX - rTextPlanets * Cos(visAngleRad) pY = centerY + rTextPlanets * Sin(visAngleRad) Set txtBox = ws.Shapes.AddTextbox(msoTextOrientationHorizontal, pX - 12, pY - 10, 24, 20) With txtBox .TextFrame.Characters.Text = pNames(i) .TextFrame.Characters.Font.Size = 9 .TextFrame.Characters.Font.Bold = True .TextFrame.HorizontalAlignment = xlHAlignCenter .TextFrame.VerticalAlignment = xlVAlignCenter .TextFrame.MarginLeft = 0 .TextFrame.MarginRight = 0 .TextFrame.MarginTop = 0 .TextFrame.MarginBottom = 0 .Line.Visible = msoFalse .Fill.Visible = msoFalse End With Next i End Sub


-----------------------------------------------------------------------------

Последний раз редактировалось Les, 22.08.2026 в 05:16.
Les вне форума   Ответить с цитированием
Старый 22.08.2026, 05:05   #3
Les
Собеседник
 
Регистрация: 08.12.2018
Сообщения: 318
Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000
По умолчанию

нанесение сетки домов
в моем примере данные берутся из ячеек столбцы O и P.

## Код макроса VBA


Код:
Sub DrawAstrologyHouses() Dim ws As Worksheet Set ws = ActiveSheet Dim centerX As Double, centerY As Double Dim rOuter As Double, rZodiacInner As Double, rPlanetCircle As Double centerX = 400: centerY = 260 rOuter = 210: rZodiacInner = 175: rPlanetCircle = 135 Dim rHouseExt As Double, rAscExt As Double rHouseExt = rOuter + 5 ' Обычный хвостик куспида rAscExt = rOuter + 25 ' Удлиненный хвостик для Асцендента (1-й дом) Dim pi As Double: pi = 3.14159265358979 Dim lastRow As Long: lastRow = ws.Cells(ws.Rows.count, "P").End(xlUp).Row If lastRow < 2 Then Exit Sub Dim r As Long, houseLong As Double, angleRad As Double Dim x1 As Double, y1 As Double, x2 As Double, y2 As Double, x3 As Double, y3 As Double, x4 As Double, y4 As Double Dim houseLineInner As Shape, houseLineOuter As Shape For r = 2 To lastRow If ws.Cells(r, "P").Value <> "" And IsNumeric(ws.Cells(r, "P").Value) Then houseLong = Val(ws.Cells(r, "P").Value) angleRad = houseLong * pi / 180 ' Внутренняя линия x1 = centerX - rPlanetCircle * Cos(angleRad) y1 = centerY + rPlanetCircle * Sin(angleRad) x2 = centerX - rZodiacInner * Cos(angleRad) y2 = centerY + rZodiacInner * Sin(angleRad) Set houseLineInner = ws.Shapes.AddLine(x1, y1, x2, y2) ' Внешняя линия x3 = centerX - rOuter * Cos(angleRad) y3 = centerY + rOuter * Sin(angleRad) Dim currentExt As Double Dim houseIndex As Long houseIndex = r - 1 ' Строка 2 = 1-й дом (ASC) ' Если это Асцендент (1-й дом), делаем его длиннее If houseIndex = 1 Then currentExt = rAscExt Else currentExt = rHouseExt x4 = centerX - currentExt * Cos(angleRad) y4 = centerY + currentExt * Sin(angleRad) Set houseLineOuter = ws.Shapes.AddLine(x3, y3, x4, y4) ' Стилизация базовых линий houseLineInner.Line.ForeColor.RGB = RGB(120, 120, 120) houseLineOuter.Line.ForeColor.RGB = RGB(120, 120, 120) houseLineInner.Line.Weight = 1 houseLineOuter.Line.Weight = 1 ' Выделение угловых домов If houseIndex = 1 Or houseIndex = 4 Or houseIndex = 7 Or houseIndex = 10 Then houseLineInner.Line.Weight = 1.75 houseLineOuter.Line.Weight = 1.75 houseLineInner.Line.ForeColor.RGB = RGB(40, 40, 40) houseLineOuter.Line.ForeColor.RGB = RGB(40, 40, 40) End If End If Next r End Sub


-----------------------------------------------------------------

Последний раз редактировалось Les, 22.08.2026 в 05:14.
Les вне форума   Ответить с цитированием
Старый 22.08.2026, 05:09   #4
Les
Собеседник
 
Регистрация: 08.12.2018
Сообщения: 318
Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000
По умолчанию

Рисуем аспекты.

Этот макрос берет список планет из столбцов A и B.
столбцы R, S и T -настройка аспектного блока
R - вид аспекта в десятичном формате, например 152,48
S - орбис
T - цвет линии аспекта
Шестнадцатеричный HEX-код (текст вроде #FF0000).
Если в ячейке возникнет ошибка или пустота, макрос по умолчанию покрасит линию аспекта в нейтральный черный цвет.

## Код макроса VBA для отрисовки аспектов


Код:
Sub DrawAstrologyAspects() Dim ws As Worksheet: Set ws = ActiveSheet ' 1. Геометрический центр и радиус (линии аспектов соединяют точки планет на rPlanetCircle) Dim centerX As Double, centerY As Double, rPlanetCircle As Double centerX = 400: centerY = 260: rPlanetCircle = 135 Dim pi As Double: pi = 3.14159265358979 ' 2. Читаем массив РЕАЛЬНЫХ ПЛАНЕТ с листа (Столбцы A и B) Dim lastRowPlanets As Long lastRowPlanets = ws.Cells(ws.Rows.count, "A").End(xlUp).Row If lastRowPlanets < 2 Then MsgBox "Нет планет для аспектирования!", vbExclamation: Exit Sub Dim pCount As Long: pCount = lastRowPlanets - 1 ReDim pNames(1 To pCount) As String ReDim pLongs(1 To pCount) As Double Dim r As Long, pIdx As Long: pIdx = 1 For r = 2 To lastRowPlanets If ws.Cells(r, 1).Value <> "" Then pNames(pIdx) = ws.Cells(r, 1).Value pLongs(pIdx) = Val(ws.Cells(r, 2).Value) pIdx = pIdx + 1 End If Next r pCount = pIdx - 1 ' 3. Читаем массив ИССЛЕДУЕМЫХ АСПЕКТОВ (Столбцы R, S, T) Dim lastRowAspects As Long lastRowAspects = ws.Cells(ws.Rows.count, "R").End(xlUp).Row If lastRowAspects < 2 Then MsgBox "Таблица исследуемых аспектов (в столбце R) пуста!", vbInformation Exit Sub End If Dim aCount As Long: aCount = lastRowAspects - 1 ReDim targetAngles(1 To aCount) As Double ReDim orbisValues(1 To aCount) As Double ReDim aspectColors(1 To aCount) As Long Dim aIdx As Long: aIdx = 1 Dim hexColor As String, cleanHex As String Dim rVal As Long, gVal As Long, bVal As Long For r = 2 To lastRowAspects If ws.Cells(r, "R").Value <> "" And IsNumeric(ws.Cells(r, "R").Value) Then targetAngles(aIdx) = Abs(Val(ws.Cells(r, "R").Value)) orbisValues(aIdx) = Abs(Val(ws.Cells(r, "S").Value)) ' Парсинг цвета из HEX формата (#XXXXXX) в столбце T hexColor = Trim(CStr(ws.Cells(r, "T").Value)) cleanHex = Replace(hexColor, "#", "") ' Если HEX-код валидный (6 символов), переводим его в RGB If Len(cleanHex) = 6 Then On Error Resume Next rVal = CInt("&H" & Mid(cleanHex, 1, 2)) gVal = CInt("&H" & Mid(cleanHex, 3, 2)) bVal = CInt("&H" & Mid(cleanHex, 5, 2)) aspectColors(aIdx) = RGB(rVal, gVal, bVal) On Error GoTo 0 Else ' Цвет по умолчанию, если формат нарушен — черный aspectColors(aIdx) = RGB(0, 0, 0) End If aIdx = aIdx + 1 End If Next r aCount = aIdx - 1 ' 4. МАТЕМАТИЧЕСКИЙ АНАЛИЗ ПАР ПЛАНЕТ Dim i As Long, j As Long, k As Long Dim lon1 As Double, lon2 As Double, rawDiff As Double, actualAspect As Double Dim rad1 As Double, rad2 As Double Dim x1 As Double, y1 As Double, x2 As Double, y2 As Double Dim aspectLine As Shape Dim matchFound As Boolean ' Перебираем каждую уникальную пару планет (комбинаторика без повторов) For i = 1 To pCount - 1 For j = i + 1 To pCount lon1 = pLongs(i) lon2 = pLongs(j) ' Считаем кратчайшее дуговое расстояние на сфере (от 0 до 180 градусов) rawDiff = Abs(lon1 - lon2) If rawDiff > 180 Then actualAspect = 360 - rawDiff Else actualAspect = rawDiff End If ' Сверяем полученное расстояние со списком искомых аспектов For k = 1 To aCount ' Условие попадания в орбис: | Факт - План | <= Орбис If Abs(actualAspect - targetAngles(k)) <= orbisValues(k) Then ' Вычисляем экранные координаты планет-участников rad1 = lon1 * pi / 180 rad2 = lon2 * pi / 180 x1 = centerX - rPlanetCircle * Cos(rad1) y1 = centerY + rPlanetCircle * Sin(rad1) x2 = centerX - rPlanetCircle * Cos(rad2) y2 = centerY + rPlanetCircle * Sin(rad2) ' Чертим линию аспекта внутри центрального круга Set aspectLine = ws.Shapes.AddLine(x1, y1, x2, y2) ' Стилизуем линию цветом из таблицы Т With aspectLine.Line .ForeColor.RGB = aspectColors(k) .Weight = 1.25 ' Если орбис очень точный (меньше 0.5 градусов), можно выделить жирнее If Abs(actualAspect - targetAngles(k)) < 0.3 Then .Weight = 2 End With matchFound = True End If Next k Next j Next i End Sub



--------------------------------

Последний раз редактировалось Les, 22.08.2026 в 05:13.
Les вне форума   Ответить с цитированием
Старый 22.08.2026, 05:20   #5
Les
Собеседник
 
Регистрация: 08.12.2018
Сообщения: 318
Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000
По умолчанию

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

## Пошаговая инструкция, куда вставить код:

1. Откройте редактор VBA.
2. В левой колонке (окно Project Explorer) найдите вашу рабочую книгу и дважды кликните по названию листа, на котором находится ваша таблица (например, Лист1 или Sheet1).
3. Важно: Не создавайте новый стандартный модуль, код должен находиться именно внутри самого листа!
4. В открывшееся пустое правое окно вставьте следующий код:


Код:
Private Sub Worksheet_Calculate() ' Это событие не умеет определять, какая конкретно ячейка изменилась, ' поэтому оно срабатывает при ЛЮБОМ пересчете формул на этом листе. On Error GoTo CleanExit ' Отключаем события, чтобы макрос сам не вызвал повторный пересчет Application.EnableEvents = False Application.ScreenUpdating = False ' Запуск ваших макросов Call DrawAstrologyChart_Final Call DrawAstrologyHouses Call DrawAstrologyAspects CleanExit: Application.EnableEvents = True Application.ScreenUpdating = True End Sub


----------------------------------

Последний раз редактировалось Les, 22.08.2026 в 05:29.
Les вне форума   Ответить с цитированием
Старый 22.08.2026, 05:26   #6
Les
Собеседник
 
Регистрация: 08.12.2018
Сообщения: 318
Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000
По умолчанию

у меня лист выглядит примерно вот так
использую офис 2000
Миниатюры
Нажмите на изображение для увеличения
Название: лист.png
Просмотров: 9
Размер:	41.1 Кб
ID:	67634  
Les вне форума   Ответить с цитированием
Старый 22.08.2026, 06:57   #7
Азъ
Собеседник
 
Аватар для Азъ
 
Регистрация: 18.01.2026
Сообщения: 665
Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000
По умолчанию

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


Но для этого надо загрузить в Excel библиотеку рассчета швейцарских эфемерид. В свое время я их брал где здесь на ARGO.
А дальше вы просто сообщаете ИИ как выглядит обращение к функции вычисления юлианской даты JDAY и рассчета планет и куспидов PLC и дело в шляпе - ИИ напишет любой код.
Азъ вне форума   Ответить с цитированием
Старый 22.08.2026, 10:37   #8
Единорог
Единорог
 
Аватар для Единорог
 
Регистрация: 30.03.2009
Сообщения: 77,451
Единорог отключил(а) отображение уровня репутации
По умолчанию

Кстати рисунок можно выводить не только на листе Эксель. VBA позволяет работать с формами, и есть специальные графические элементы. Можно и на форме рисовать, а можно и в графическом элементе. Только надо код писать.
__________________
Единорог вне форума   Ответить с цитированием
Старый 22.08.2026, 11:51   #9
Азъ
Собеседник
 
Аватар для Азъ
 
Регистрация: 18.01.2026
Сообщения: 665
Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000Азъ репутация выше +2000
По умолчанию

Цитата:
Сообщение от Единорог
Кстати рисунок можно выводить не только на листе Эксель. VBA позволяет работать с формами, и есть специальные графические элементы. Можно и на форме рисовать, а можно и в графическом элементе. Только надо код писать.


Именно эти графические элементы использовались при построении картинки, которую привел Lex.
Азъ вне форума   Ответить с цитированием
Старый 22.08.2026, 12:48   #10
Les
Собеседник
 
Регистрация: 08.12.2018
Сообщения: 318
Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000
По умолчанию

предыдущий вариант заточен под ручной ввод времени
чтобы сделать изменение времени кнопками (формы excel, счетчики)
надо

1) в макросе DrawAstrologyChart вместо

Dim shp As Shape
For Each shp In ws.Shapes
shp.Delete
Next shp

заменить на


Код:
Dim shp As Shape For Each shp In ActiveSheet.Shapes ' Проверяем тип объекта. ' Тип 8 — это элементы управления формы (счетчики, кнопки). Их мы НЕ удаляем! If shp.Type <> 8 Then shp.Delete End If Next shp


2) затем с листа удаляем весь код Private Sub Worksheet_Calculate

3) создаем один общий макрос для запуска
Открываем стандартный модуль (где находится наш основной макрос DrawAstrologyChart) и в самом низу добавлем этот код. Он будет служить «пультом управления» для всех счетчиков:


Код:
Sub RunOnSpinnerClick() ' Этот макрос будет запускаться каждый раз, когда вы кликаете на любой счетчик On Error GoTo CleanExit Application.ScreenUpdating = False Application.EnableEvents = False ' Запуск построения вашей космограммы Call DrawAstrologyChart_Final ' Call DrawAstrologyHouses ' Call DrawAstrologyAspects_Filtered CleanExit: Application.EnableEvents = True Application.ScreenUpdating = True End Sub


затем идем на страницу, создаем счетчики, и назначаем каждому (год, месяц, день и тд) этот макрос Sub RunOnSpinnerClick

работает изумительно!
Les вне форума   Ответить с цитированием
Старый 22.08.2026, 14:30   #11
Единорог
Единорог
 
Аватар для Единорог
 
Регистрация: 30.03.2009
Сообщения: 77,451
Единорог отключил(а) отображение уровня репутации
По умолчанию

Цитата:
Сообщение от Азъ
Именно эти графические элементы использовались при построении картинки, которую привел Lex.
__________________
Единорог вне форума   Ответить с цитированием
Старый 24.08.2026, 05:48   #12
Les
Собеседник
 
Регистрация: 08.12.2018
Сообщения: 318
Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000
По умолчанию

пришлось полностью переделать аспектный блок
были проблемы с отрисовкой и маленькими орбисами аспектов


добавил разделение отображаемых аспектов на сходящиеся и расходящиеся


макрос берет данные из столбцов A (обозначение планеты), B (долгота) и AA (скорость)

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



Код:
Sub DrawAstrologyAspects() Dim ws As Worksheet Set ws = ActiveSheet ' Универсально работает с текущим активным листом ' 1. Удаление старых линий аспектов Dim shp As Shape For Each shp In ws.Shapes If InStr(shp.Name, "Aspect_") = 1 Then shp.Delete Next shp ' 2. Чтение флагов фильтрации из ячеек U2 и V2 Dim showConverging As Boolean Dim showDiverging As Boolean Dim flagU As String, flagV As String flagU = Trim(CStr(ws.Range("U2").Value)) flagV = Trim(CStr(ws.Range("V2").Value)) ' Если обе заполнены или обе пусты — показываем всё If (flagU <> "" And flagV <> "") Or (flagU = "" And flagV = "") Then showConverging = True showDiverging = True Else showConverging = (flagU <> "") showDiverging = (flagV <> "") End If ' 3. Геометрические параметры карты Dim centerX As Double, centerY As Double, rPlanetCircle As Double centerX = 400: centerY = 260: rPlanetCircle = 135 Dim pi As Double: pi = 3.14159265358979 ' 4. Чтение данных планет (Координаты и Скорости) Dim lastRowPlanets As Long lastRowPlanets = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row If lastRowPlanets < 2 Then Exit Sub Dim pCount As Long: pCount = 0 Dim r As Long For r = 2 To lastRowPlanets If ws.Cells(r, 1).Value <> "" And IsNumeric(ws.Cells(r, 2).Value) Then pCount = pCount + 1 End If Next r If pCount < 2 Then Exit Sub ReDim pNames(1 To pCount) As String ReDim pLongs(1 To pCount) As Double ReDim pSpeeds(1 To pCount) As Double Dim pIdx As Long: pIdx = 1 For r = 2 To lastRowPlanets If ws.Cells(r, 1).Value <> "" And IsNumeric(ws.Cells(r, 2).Value) Then pNames(pIdx) = ws.Cells(r, 1).Value pLongs(pIdx) = CDbl(ws.Cells(r, 2).Value) ' Считываем скорость из скрытого столбца AA If IsNumeric(ws.Cells(r, "AA").Value) Then pSpeeds(pIdx) = CDbl(ws.Cells(r, "AA").Value) Else pSpeeds(pIdx) = 0# End If pIdx = pIdx + 1 End If Next r pCount = pIdx - 1 ' 5. Чтение таблицы исследуемых аспектов (Столбцы R, S, T) Dim lastRowAspects As Long lastRowAspects = ws.Cells(ws.Rows.Count, "R").End(xlUp).Row If lastRowAspects < 2 Then Exit Sub Dim aCount As Long: aCount = 0 For r = 2 To lastRowAspects If ws.Cells(r, "R").Value <> "" And IsNumeric(ws.Cells(r, "R").Value) Then aCount = aCount + 1 Next r If aCount = 0 Then Exit Sub ReDim targetAngles(1 To aCount) As Double ReDim orbisValues(1 To aCount) As Double ReDim aspectColors(1 To aCount) As Long Dim aIdx As Long: aIdx = 1 Dim hexColor As String, cleanHex As String Dim rVal As Long, gVal As Long, bVal As Long For r = 2 To lastRowAspects If ws.Cells(r, "R").Value <> "" And IsNumeric(ws.Cells(r, "R").Value) Then targetAngles(aIdx) = Abs(CDbl(ws.Cells(r, "R").Value)) orbisValues(aIdx) = Abs(CDbl(ws.Cells(r, "S").Value)) hexColor = Trim(CStr(ws.Cells(r, "T").Value)) cleanHex = Replace(hexColor, "#", "") If Len(cleanHex) = 6 Then On Error Resume Next rVal = CInt("&H" & Mid(cleanHex, 1, 2)) gVal = CInt("&H" & Mid(cleanHex, 3, 2)) bVal = CInt("&H" & Mid(cleanHex, 5, 2)) aspectColors(aIdx) = RGB(rVal, gVal, bVal) On Error GoTo 0 Else aspectColors(aIdx) = RGB(0, 0, 0) End If aIdx = aIdx + 1 End If Next r aCount = aIdx - 1 ' 6. Математический анализ пар планет с АДАПТИВНЫМ ШАГОМ ВРЕМЕНИ Dim i As Long, j As Long, k As Long Dim lon1 As Double, lon2 As Double, rawDiff As Double, actualAspect As Double Dim speed1 As Double, speed2 As Double Dim rad1 As Double, rad2 As Double Dim x1 As Double, y1 As Double, x2 As Double, y2 As Double Dim aspectLine As Shape Dim futureLon1 As Double, futureLon2 As Double Dim futureRawDiff As Double, futureAspect As Double ' Переменные для адаптивного шага Dim relSpeed As Double Dim timeStep As Double Dim curDistToTarget As Double, futDistToTarget As Double Dim isApplying As Boolean Dim skipAspect As Boolean For i = 1 To pCount - 1 For j = i + 1 To pCount Dim matchFoundInOrbis As Boolean matchFoundInOrbis = False lon1 = pLongs(i) lon2 = pLongs(j) speed1 = pSpeeds(i) speed2 = pSpeeds(j) ' Кратчайшее текущее расстояние на окружности rawDiff = Abs(lon1 - lon2) If rawDiff > 180 Then actualAspect = 360# - rawDiff Else actualAspect = rawDiff ' Предварительно проверяем, образует ли эта пара хоть какой-то аспект из таблицы ' чтобы зря не вычислять динамику времени For k = 1 To aCount If Abs(actualAspect - targetAngles(k)) <= orbisValues(k) Then matchFoundInOrbis = True Exit For End If Next k ' Если аспект найден, рассчитываем сходимость с адаптивным шагом If matchFoundInOrbis Then ' Вычисляем относительную скорость изменения дуги между планетами relSpeed = Abs(speed2 - speed1) ' Рассчитываем индивидуальный временной шаг: ' Нам нужно, чтобы за этот шаг взаимное расстояние изменилось ровно на 0.0001° If relSpeed > 0.00001 Then timeStep = 0.0001 / relSpeed ' Ставим жесткие защитные лимиты на шаг: If timeStep < 0.00001 Then timeStep = 0.00001 ' Защита от слишком быстрого шага (Луна) If timeStep > 0.5 Then timeStep = 0.5 ' Защита от слишком огромного шага (стоянки) Else ' Если скорости планет абсолютно равны или они стоят — ставим стандартный шаг timeStep = 0.01 End If ' Моделируем индивидуальный шаг вперед во времени futureLon1 = lon1 + (speed1 * timeStep) futureLon2 = lon2 + (speed2 * timeStep) ' Удержание координат в пределах [0; 360) futureLon1 = futureLon1 - (Int(futureLon1 / 360#) * 360#) futureLon2 = futureLon2 - (Int(futureLon2 / 360#) * 360#) If futureLon1 < 0 Then futureLon1 = futureLon1 + 360# If futureLon2 < 0 Then futureLon2 = futureLon2 + 360# ' Будущее кратчайшее расстояние futureRawDiff = Abs(futureLon1 - futureLon2) If futureRawDiff > 180 Then futureAspect = 360# - futureRawDiff Else futureAspect = futureRawDiff ' Повторно проходим по аспектам для фильтрации и отрисовки For k = 1 To aCount If Abs(actualAspect - targetAngles(k)) <= orbisValues(k) Then ' СХОДИМОСТЬ: тренд изменения отклонения до точного аспекта curDistToTarget = Abs(actualAspect - targetAngles(k)) futDistToTarget = Abs(futureAspect - targetAngles(k)) If futDistToTarget < curDistToTarget Then isApplying = True Else isApplying = False End If ' Фильтрация skipAspect = False If isApplying And Not showConverging Then skipAspect = True If Not isApplying And Not showDiverging Then skipAspect = True ' Рисование If Not skipAspect Then rad1 = lon1 * pi / 180# rad2 = lon2 * pi / 180# x1 = centerX - rPlanetCircle * Cos(rad1) y1 = centerY + rPlanetCircle * Sin(rad1) x2 = centerX - rPlanetCircle * Cos(rad2) y2 = centerY + rPlanetCircle * Sin(rad2) Set aspectLine = ws.Shapes.AddLine(x1, y1, x2, y2) aspectLine.Name = "Aspect_" & pNames(i) & "_" & pNames(j) With aspectLine.Line .ForeColor.RGB = aspectColors(k) .Weight = 1.25 .DashStyle = msoLineSolid End With End If End If Next k End If Next j Next i End Sub



этот вариант защищен от эффекта «зависания» медленных планет и исключает «проскакивание» быстрых, хотя все может быть...

Последний раз редактировалось Les, 24.08.2026 в 05:53.
Les вне форума   Ответить с цитированием
Старый 24.08.2026, 05:59   #13
Les
Собеседник
 
Регистрация: 08.12.2018
Сообщения: 318
Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000
По умолчанию

Цитата:
Сообщение от Les

' Call DrawAstrologyHouses
' Call DrawAstrologyAspects_Filtered




чтобы все макросы запускались, надо в RunOnSpinnerClick раскомментировать эти строки
забыл (
Les вне форума   Ответить с цитированием
Старый 24.08.2026, 06:06   #14
Les
Собеседник
 
Регистрация: 08.12.2018
Сообщения: 318
Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000Les репутация выше +2000
По умолчанию

вот как сейчас выглядит лист
в левом верхнем углу формула для пересчета юлианской даты обратно в формат ДД ММ ГГГ ЧЧ ММ СС


Библиотека Swiss Ephemeris содержит встроенную функцию swe_revjul. Она выполняет строго обратную задачу: принимает дробное число Юлианской даты (JD) и раскладывает его на исходный год, месяц, день и дробный час. [1, 2]
Поскольку Excel 2000 (как и современные версии) физически не поддерживает даты ранее 1 января 1900 года, решением является сборка и возврат даты в текстовом формате ДД.ММ.ГГГГ ЧЧ:ММ:СС. В таком виде Excel не будет пытаться превратить её в своё внутреннее число и корректно отобразит любой исторический год (даже до нашей эры с минусом).



Код:
Public Function RevJDay(ByVal JD As Double, Optional ByVal GregFlg As Integer) As String' Переводит Юлианскую дату обратно в формат ДД.ММ.ГГГГ ЧЧ:ММ:СС' Поддерживает любые исторические даты (включая древние и до 1900 года)' JD = Юлианская дата' GregFlg = 1 для Григорианского календаря (по умолчанию), 0 для Юлианского Dim year As Long Dim month As Long Dim day As Long Dim hourDouble As Double Dim hourInt As Integer Dim minInt As Integer Dim secDouble As Double Dim secInt As Integer Dim sDay As String, sMonth As String, sYear As String Dim sHour As String, sMin As String, sSec As String ' Если флаг календаря не указан, используем Григорианский по умолчанию If IsMissing(GregFlg) Or GregFlg = 0 Then GregFlg = 1 ' Вызываем функцию из swedll32.dll ' Внимание: добавляем микро-сдвиг 0.0000001 для защиты от погрешности округления Double Call swe_revjul(JD + 0.0000001, GregFlg, year, month, day, hourDouble) ' Разбираем дробный час (hourDouble) на Часы, Минуты и Секунды hourInt = Fix(hourDouble) minInt = Fix((hourDouble - hourInt) * 60) secDouble = ((hourDouble - hourInt) * 60 - minInt) * 60 secInt = Round(secDouble) ' Корректировка переполнения секунд при округлении If secInt >= 60 Then secInt = 0 minInt = minInt + 1 End If If minInt >= 60 Then minInt = 0 hourInt = hourInt + 1 End If ' Форматируем текстовые составляющие с ведущими нулями sDay = Right$("0" & day, 2) sMonth = Right$("0" & month, 2) sYear = Format$(year, "0000") ' Корректно отобразит даже 4-й или 500-й год sHour = Right$("0" & hourInt, 2) sMin = Right$("0" & minInt, 2) sSec = Right$("0" & secInt, 2) ' Собираем финальную текстовую строку для ячейки Excel RevJDay = sDay & "." & sMonth & "." & sYear & " " & sHour & ":" & sMin & ":" & sSec End Function


-----------------
Миниатюры
Нажмите на изображение для увеличения
Название: Снимок экрана от 2026-06-05 18-52-11.png
Просмотров: 7
Размер:	40.3 Кб
ID:	67656  

Последний раз редактировалось Les, 24.08.2026 в 06:12.
Les вне форума   Ответить с цитированием
Старый 24.08.2026, 06:40   #15
ольвия
Собеседник
 
Аватар для ольвия
 
Регистрация: 07.02.2011
Адрес: Владимирская Русь
Сообщения: 79,281
ольвия репутация выше +2000ольвия репутация выше +2000ольвия репутация выше +2000ольвия репутация выше +2000ольвия репутация выше +2000ольвия репутация выше +2000ольвия репутация выше +2000ольвия репутация выше +2000ольвия репутация выше +2000ольвия репутация выше +2000ольвия репутация выше +2000
По умолчанию

Интересно попробовать. Правда не знаю зачем ( прога есть) и времени сейчас нет. Но, все равно, любопытно.
__________________
Esse. quam videri.

БЛОГ на ARGO jour​​​nal
ольвия вне форума   Ответить с цитированием
Ответ


Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +1, время: 14:27.


Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
© 1995-2026, ARGO