Увеличение даты на месяц (год)

Автор siti, 12 августа 2022, 14:06

0 Пользователи и 1 гость просматривают эту тему.

siti

Есть в ячейке Calc любая дата, например 10.08.2022
Как ее увеличить на один месяц до 10.09.2022, или на год до 10.08.2023 с учетом высокосных годов и разного кол-ва дней в месяце?
Можно это сделать как то просто, не разбирая дату на день/месяц/год и не собирая обратно?

eeigor

Можно. Добавляем 1 год:
=EDATE(StartDate;12)
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

sokol92

В таких задачах самое важное - понимать правила игры. Например, что будет (должно быть), если добавить один месяц к 30.01.2022?
Владимир.

eeigor

Цитата: sokol92 от 12 августа 2022, 14:20Например, что будет (должно быть), если добавить один месяц к 30.01.2022?
28.02.2022 - конец другого месяца с учётом високосных годов и пр., как указал автор.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

mikekaganski

Цитата: eeigor от 12 августа 2022, 14:28
Цитата: sokol92 от 12 августа 2022, 14:20Например, что будет (должно быть), если добавить один месяц к 30.01.2022?
28.02.2022 - конец другого месяца с учётом високосных годов и пр., как указал автор.

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

=EDATE($A$1;ROW()-1)

даст снова 30й день для марта и т.д.

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

=EDATE(A1;1)

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

sokol92

#5
Это - одна из интерпретаций. То есть:
28.01.2022 + 1 месяц = 28.02.2022
29.01.2022 + 1 месяц = 28.02.2022
30.01.2022 + 1 месяц = 28.02.2022
31.01.2022 + 1 месяц = 28.02.2022

Если надо через месяц сдать проект (экзамен), то лишние три дня не помешают. А вот для приговоренных... :)
Владимир.

eeigor

Тогда просто прибавляйте дни к начальной дате:
=StartDate+30*2 - прибавляет 2 условных месяца и возвращает какую-то условную дату.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

sokol92

#7
Правила игры для функции Oracle ADD_MONTH:
Если дата является последним днем месяца или если в результирующем месяце меньше дней, чем номер дня даты, то результатом является последний день результирующего месяца. В противном случае результат имеет тот же компонент дня, что и дата.
То есть (для вышеуказанной функции): 28.02.2022 + 1 месяц = 31.03.2022
Владимир.

siti

Делаю чтото типа планировщика задач. Дя повторяющихся задач дата очередной активации задачи переносится на период повторения( неделя, месяц, год).
С годом допустимо просто +365 сделать. Високосный год- ерунда.
Неделя тоже +7 работает к дате из ячейки.
Главное месяц.
Для упрощения - дат с днем больше чем 28 число в ячейках не будет.
Соответственно если указана дата 25.08.2022 то ее надо будет сдвинуть на 25.09.2022
Для усложнения вопроса можно конечно попытаться сделать если дата является последним днем месяца то переносить на последний день следующего.

siti

Хотя опять же если ставить 28 число каждого месяца, то с февраля на март дата улетит на 31 марта.
Получается надо добавлять еще один тип повторения- «последнее число месяца», либо не ставить дату позднее 27 числа

eeigor

Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

siti

Цитата: eeigor от 14 августа 2022, 16:14
Ну вот, Вы сами всё знаете.
Я только не понял в итоге, как лучше месяц плюсануть? Мне не формулу надо, а в VB макросом

eeigor

#12
Например, вычислить позицию ячейки B2 и присвоить ей формулу.
oSheet = ThisComponent.CurrentController.ActiveSheet
oCell = oSheet.getCellByPosition(1, 1)  '.getCellRangeByName("B2")
oCell.Formula = "=EDATE(A2;1)"
oCell.Formula = "=A2+30"

Можно в цикле.
Sub Main()
''' Calls: GetCurrentRegion(), SetFormulaR1C1

Rem Demo code (not tested):
   Dim oSheet As Object, oRange As Object, oCell As Object
   Dim sFormulaR1C1$: sFormulaR1C1 = "EDATE(RC[-1];1)  'данные лежат в соседнем столбце слева: C[-1] текущей строки R

   oSheet = ThisComponent.CurrentController.ActiveSheet
   oRange = oSheet.getCellByPosition(0, 0)  'верхний левый угол диапазона
   oRange = GetCurrentRegion(oRange)  'текущий диапазон
   Dim i&
   For i = 0 To oRange.Rows.Count - 1  'For i = 1 To... #если надо пропустить строку заголовков столбцов
       oCell.getCellByPosition(1, i)
       Call SetFormulaR1C1(sFormulaR1C1, oCell)
   Next
End Sub

Function GetCurrentRegion(oRange As Object) As Object  '-> ScCellCursorObj
   Dim oCursor As Object
   oCursor = oRange.Spreadsheet.createCursorByRange(oRange)
   ' Expand the cursor into the region containing the cells to which
   ' it currently points. A region is a cell range bounded by empty cells.
   oCursor.collapseToCurrentRegion()
   GetCurrentRegion = oCursor  'oRange.Spreadsheet.getCellRangeByName(oCursor.AbsoluteName)
End Function

Sub SetFormulaR1C1(sFormulaR1C1$, oCell As Object)
   Dim oParser As Object
   oParser = ThisComponent.CreateInstance("com.sun.star.sheet.FormulaParser")
   oParser.FormulaConvention = com.sun.star.sheet.AddressConvention.XL_R1C1
   oCell.Tokens = oParser.parseFormula(sFormulaR1C1, oCell.CellAddress)
End Sub


Текущий диапазон не должен содержать разрывов и должен быть ограничен пустыми строками снизу/столбцами справа (по ситуации; а то и сверху и слева).

Ещё вопросы есть?
Примечание. Я процедуру Main не тестировал: набрал прямо здесь. Если не проходит - сигнализируйте...
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

siti

#13
что-то я не так делаю  ???
формат обеих ячеек - дата

economist

Даты, Числа - в Calc лучше никогда не форматировать по центру. Путь они сами выровняются (текст - влево, даты/числа-вправо).
Формат не меняет содержимого ячейки (только ее вид). А формула работает только с содержимым.
Функции можно писать на русском и английском, но в соответствии с флажком настройках Alt+F12 - ...Calc - Формулы - Использовать английские
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...