:: Не фоксом единым
Список месяцев
Артём

Сообщений: 116
Дата регистрации: 23.04.2001
Можно ли сформировать таблицу (точнее хочу SQL запрос), со всеми месяцами и годами с 2010 года (например).
то есть таблицу такого вида
2010 01
2010 02
...
2010 12
2011 01
и так до текущего месяца.

Я это делал просто создав таблицу dbf и заполнял нужными датами в цикле. Может, можно создать одной командой или двумя?

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

Может, даже так. есть некоторый запрос в котором минимальная дата и максимальная. к примеру
SELECT date FROM sales
как переделать его в список месяцев и годов без пропусков.



Исправлено 1 раз(а). Последнее : Артём, 04.12.22 00:28
Ratings: 0 negative/0 positive
Re: Список месяцев
PaulWist

Сообщений: 14618
Дата регистрации: 01.04.2004
Серверный диалект какой?


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Список месяцев
Артём

Сообщений: 116
Дата регистрации: 23.04.2001
я на фокс про. надо, как и всегда, идею, мелочи додумаю.
Ratings: 0 negative/0 positive
Re: Список месяцев
PaulWist

Сообщений: 14618
Дата регистрации: 01.04.2004
Артём
Можно ли сформировать таблицу (точнее хочу SQL запрос), со всеми месяцами и годами с 2010 года (например).
то есть таблицу такого вида
2010 01
2010 02
...
2010 12
2011 01
и так до текущего месяца.

Я это делал просто создав таблицу dbf и заполнял нужными датами в цикле. Может, можно создать одной командой или двумя?

Создай на 100 лет вперёд. (таблица с годами-месяцами, с последовательно возрастающими числами - это нужные таблицы в БД, их надо всегда иметь )


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/1 positive
Re: Список месяцев
Владимир Максимов

Сообщений: 14098
Откуда: Москва
Дата регистрации: 02.09.2000
Паша хочет сказать, что нужно иметь таблицу-календарь. На 100 лет вперед - это 365,25*100 = 36 525 записей. Вполне посильное количество записей для DBF. Ну, если это кажется слишком много, то можно создать календарь на несколько лет вперед и каждый год добавлять дни очередного года

Таблица должна быть постоянная. Не для какой-то одной операции, а обычный постоянный справочник в базе данных. Точно такой же, как справочник поставщиков/клиентов или номенклатур.

Очень много всего "завязано" на календарь. Поэтому всегда лучше иметь его "под рукой", а не создавать "на лету".

Какие еще поля, кроме собственно даты - это зависит от приложения. Но обычно еще отдельно делают 3 поля: Год, Месяц, День. Соответственно, получить список месяцев за период - выборка с Distinct по этой таблице с .. по ...
Ratings: 0 negative/0 positive
Re: Список месяцев
PaulWist

Сообщений: 14618
Дата регистрации: 01.04.2004
Владимир Максимов
... Поэтому всегда лучше иметь его "под рукой", а не создавать "на лету".

Добавлю к словам Владимира, почему "на лету" плохо, в этом случае нет индексов, не будет Rushmore оптимизации.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Список месяцев
AndyNigmatec

Сообщений: 1573
Откуда: Волгоград
Дата регистрации: 28.06.2015
Я бы еще добавил (как минимум) в такую табл/справочник признак рабочий/выходной день.
Ratings: 0 negative/0 positive
Re: Список месяцев
of63
Автор

Сообщений: 25244
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
PaulWist
Артём
Можно ли сформировать таблицу (точнее хочу SQL запрос), со всеми месяцами и годами с 2010 года (например).
то есть таблицу такого вида
2010 01
2010 02
...
2010 12
2011 01
и так до текущего месяца.

Я это делал просто создав таблицу dbf и заполнял нужными датами в цикле. Может, можно создать одной командой или двумя?

Создай на 100 лет вперёд. (таблица с годами-месяцами, с последовательно возрастающими числами - это нужные таблицы в БД, их надо всегда иметь )

Неочень приятное решение, что "давйте все ID, или все даты, или диапазон, перечислим". Язык (не фоксовый, общеупотребимый) этого не позвооляет, не имеет синтаксиса, которй разрабыб ы реализовали. Поэтому только подпрограммы, это неизбежно... (и было долго... ) )
Ratings: 0 negative/0 positive
Re: Список месяцев
of63
Автор

Сообщений: 25244
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
AndyNigmatec
Я бы еще добавил (как минимум) в такую табл/справочник признак рабочий/выходной день.

Это сложная прога (выходные дни в РФ, или в другой стране)
Интересно, как ты бы ее решил?
Ratings: 0 negative/0 positive
Re: Список месяцев
Владимир Максимов

Сообщений: 14098
Откуда: Москва
Дата регистрации: 02.09.2000
of63
AndyNigmatec
Я бы еще добавил (как минимум) в такую табл/справочник признак рабочий/выходной день.

Это сложная прога (выходные дни в РФ, или в другой стране)
Интересно, как ты бы ее решил?

Вот именно как прога - сложная. А как таблица - простая.

Если стоит задача ведения нескольких календарей, то несколько таблиц и создается (разный график выходных и рабочих дней). Отдельная таблица под каждый вид/тип календаря.

А вот написать прогу, которая бы по некоему алгоритму делала вычисления, например, выходных дней - невозможно. Это не формализуется. Под это дело обычно выходит постановлении правительства. Как ты эти постановления запрограммируешь? Только прямым перечислением дат. Та же таблица, только в виде набора констант. В общем, то же самое, но "в профиль"
Ratings: 0 negative/0 positive
Re: Список месяцев
of63
Автор

Сообщений: 25244
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Списки дней, выходных, выношу в список нештатных дат, в "INI" конкретное конторы/филиала. Куча способов вести (возможность заносить оператору) эти даты в "календаре" нештатных выходных дней, и куча способов заставить оператора это делать. Физически - это ЗПТ список дат, или табличка наращиваемая... Больше организационная пробла... Не сложная

> А вот написать прогу, которая бы по некоему алгоритму делала вычисления, например, выходных дней - невозможно. Это не формализуется. Под это дело обычно выходит постановлении правительства. Как ты эти постановления запрограммируешь? Только прямым перечислением дат. Та же таблица, только в виде набора констант. В общем, то же самое, но "в профиль"

Это (например вышеуказаннми списками нештатных рабочих/ нерабочих дат) делается, естественно. В "1С" это же делается?, там не боги силят, нормальные писатели... И они это делают... Мтк это вообще не пробла...

Вот, первая попавшаяся прога по поводу... и таких можно много написать.



Исправлено 1 раз(а). Последнее : of63, 23.12.22 00:57
Ratings: 0 negative/0 positive
Re: Список месяцев
Владимир Максимов

Сообщений: 14098
Откуда: Москва
Дата регистрации: 02.09.2000
of63
Физически - это ЗПТ список дат, или табличка наращиваемая...

И я о том же. О табличке...

Ты что доказать-то хочешь? Что написать программный код - это проще/удобнее, чем расставить галки в таблице? Что при поиске даты вызвать функцию - это проще/удобнее, чем запрос к таблице? В чем предмет спора?
Ratings: 0 negative/0 positive
Re: Список месяцев
of63
Автор

Сообщений: 25244
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Функцией, эти даты непредсказуемых прогулов, сделать невозможно
Я их записываю тааблицей, в списке, формата ЗПТ-список,

Тебе проще создать "таблицу" (записанную в неком файле старта, просто перечень дат, через запятую (например 'выхи: 2023, 01-11, ...)

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

Я для себя создал понятие - "ЗПТ-список" - список нечт, через запятую, в символьной строке выражается... Не рекламирую, таблица - тоже хороший вариант, но "таблица" все же, не переменная...

У меня вот так это выглядело (выходные нештатные дни), умерло, потому что в законофигде это уже непонадобилось
Настройки]

; ГГГГ: [Д]ДММ[ГГ][ГГ][.дней]
Дополнительный Нерабочий День ДДММГГГГ = 2014: 101.8,105.4,905.3, 1206.2, 111.4, 2016: 2402, 2022: 0703, 0305, 1005

Пишу, обычно, всякую "универсальную" дрянь, типа
Часть текста скрыта
********************************************************************************
* Проверяет (1D) на начало/конец месяца, или диапазона месяцев [2-3]
* Возвращает 1/-1 - начало/конец месяца (или диапазона), 0 - в остальных случаях
* при указании (4N=год), также проверяет на год
********************************************************************************
FUNCTION IsLimDate
LPARAMETE m.parD, m.parN1, m.parN2, m.parY
PRIVATE ALL LIKE ?
m.p = PCOUNT()
#DEFINE Самовызов IsLimDate
DO CASE
* Просто проверка даты (1DT) на начало/конец месяца
CASE m.p=1
RETURN ICASE(EMPTY(m.parD), 0,;
DAY(m.parD)=1, 1,; && заданная дата - начало месяца
DAY(m.parD+1)=1, -1,; && заданная дата - конец месяца
0)
* Задан период месяцев [2N,3N]. Проверяем дату (1) на принадлежность периоду
* В [4N] м.б. задан год, которому принадлежит период
CASE m.p>=3 .AND. VARTYPE(m.parN1)="N" .AND. VARTYPE(m.parN2)="N"
m.y = IIF(m.p<4 .OR. NEVL(m.parY), .NULL., m.parY) && речь идет только об этом годе
RETURN ICASE(EMPTY(m.parD) .OR. (!ISNULL(m.y) .AND. !YEAR(m.parD)=m.y), 0,; && заданная дата - вообще не заданного года
DAY(m.parD)=1 .AND. MONTH(m.parD)=m.parN1, 1,; && заданная дата - начало заданного месяца (2N)
DAY(m.parD+1)=1 .AND. MONTH(m.parD)=m.parN2, -1,; && заданная дата - конец заданного месяца (3N)
0)
* Спецвызов для проверки, не является ли (1DT) особенной датой типа (2C), где
* (2C) принимает значение П из списка возможных периодов: НД, НПД, КВ, ПГ, Пасха (их расшифровку см. в программе).
* Причем П можно уподробить следующими префиксами и суффиксами:
* П - внутри к.-л. периода, включая границы
* №П - номер периода (например, квартала, или недели. Номер [не]рабочего дня в серии [не]рабочих дней. Нумерация с 1.)
* $П - длительность периода
* ?П - название периода (например, квартала, или недели)
* .П - началом
* П. - концом
* [3N] - здесь можно указать проверку на год
CASE m.p>=2 .AND. VARTYPE(m.parN1)="C"
m.y = IIF(m.p<3 .OR. NEVL(m.parN2), .NULL., m.parN2) && речь идет только об этом годе
m.f = ALLTRIM(m.parN1) && запрашиваемая информация о периоде, а именно хотят узнать факт принадлежности периоду, или:
m.m = IIF("№"$m.f, 1, 0)+; && 0 - номер периода ([не]рабочего дня в серии [не]рабочих дней. Нумерация с 1.)
IIF("$"$m.f, 2, 0)+; && 1 - длительность периода
IIF("?"$m.f, 4, 0)+; && 2 - название периода
IIF(m.f=".", 8, 0)+; && 3 - факт начала периода
IIF(RIGHT(m.f,1)=".", 16, 0) && 4 - факт конца периода
m.f = CHRTRAN(m.f, "№", "")
m.f = CHRTRAN(m.f, "$", "")
m.f = CHRTRAN(m.f, "?", "")
m.f = ALLTRIM(m.f, 1, ".", " ")
m.r = ICASE(BITTEST(m.m,0), 0,; && номер периода
BITTEST(m.m,1), 0,; && длительность периода
BITTEST(m.m,2), "",; && название периода
.F.) && факт принадлежности даты (1DT) к.-л. части периода (началу, концу, всему)
DO CASE
CASE EMPTY(m.parD) && измеряемая дата не задана
CASE !ISNULL(m.y) .AND. !YEAR(m.parD)=m.y && наложен фильтр на измеряемый год, и год не подошел
CASE INLIST(m.f, "НД", "РД") && нерабочий день, рабочий день
m.x = ICASE(Самовызов(m.parD, "ВД"), "ВД",; && суббота и воскресенье - всегда нерабочие дни
Самовызов(m.parD, "НПД"), "НПД",; && Нерабочий праздничный день (например, 01-08.01 - новогодние каникулы)
Самовызов(m.parD, "ДНД"), "ДНД",; && дополнительный нерабочий день
DOW(m.parD,2)=1 .AND. Самовызов(m.parD, "НПДП"), "НПДП",; && нерабочий понедельник, по причине переноса НПД с выходного на понедельник
"")
IF IIF(m.f="НД", !EMPTY(m.x), EMPTY(m.x)) && измеряемый день - [не]рабочий
STORE 0 TO m.a, m.b && количество дней назад, и вперед, до достижения последнего [не]рабочего дня
IF !EMPTY(BITCLEAR(m.m,2)) && хотят знать что-то связанное с знанием длины диапазона [не]рабочих дней
DO WHILE Самовызов(m.parD-m.a-1, m.f) && считаем [не]рабочее кол. дней назад
m.a = m.a+1
ENDDO
DO WHILE Самовызов(m.parD+m.b+1, m.f) && считаем [не]рабочее кол. дней вперед
m.b = m.b+1
ENDDO
ENDIF
IF ICASE(BITTEST(m.m,3), m.a=0,; && начало серии [не]рабочих дней
BITTEST(m.m,4), m.b=0,; && конец серии [не]рабочих дней
.T.)
m.r = ICASE(BITTEST(m.m,0), 1+m.a,; && номер [не]рабочего дня в серии [не]рабочих дней. Нумерация с 1.
BITTEST(m.m,1), 1+m.a+m.b,; && длина серии [не]рабочих дней
BITTEST(m.m,2) .AND. !EMPTY(m.x), Самовызов(m.parD, "?"+m.x),; && название периода нерабочих дней
BITTEST(m.m,2), "",;
.T.)
ENDIF
ENDIF
CASE m.f="ВД" && обычный выходной день в РФ (суббота и воскресение)
m.x = ICASE(DOW(m.parD,2)=6, 1,; && суббота
DOW(m.parD,2)=7, 2,; && воскресенье
0)
IF ICASE(EMPTY(m.x), .F.,; && дата вообще не в периоде
BITTEST(m.m,3), m.x=1,; && факт начала периода
BITTEST(m.m,4), m.x=2,; && факт конца периода
.T.) && запрашивают что-то о периоде. Дата внутри периода
m.r = ICASE(BITTEST(m.m,0), m.x,; && номер периода
BITTEST(m.m,1), 2,; && длительность периода
BITTEST(m.m,2), GETWORDNUM("Суббота,Воскресенье", m.x, ЗПТ),; && название периода
.T.) && факт начала/конца периода
ENDIF
CASE m.f="ДНД" && дополнительный нерабочий день в РФ, назначается правительством РФ
IF !TYPE("m.ДополнительныйНерабочийДеньДДММГГГГ")="U" && список дат дополнительных нерабочих дней (ДНД), и их наименования (см. файл LOCAL.ini)
IF !EMPTY(m.ДополнительныйНерабочийДеньДДММГГГГ) && список ДНД может состоять из: ГГГГ: ДДММГГГГ, ДДММГГГГ.n, может включать "(наименование)" где n - кол. выходных дней
m.y = YEAR(m.parD) && если умолчательный год не указан, то считаем, что умолчательный год - это год измерения
FOR m.i=1 TO GETWORDCOUNT(m.ДополнительныйНерабочийДеньДДММГГГГ, ЗПТ+ТСЗ) && перебираем элементы списка ДНД
m.x = ALLTRIM(GETWORDNUM(m.ДополнительныйНерабочийДеньДДММГГГГ, m.i, ЗПТ+ТСЗ))
IF EMPTY(m.x)
LOOP
ENDIF
m.n = "ДНД" && название периода, умолчательное значение
DO WHILE .T. && отрезаем слева указания о смене умолчательного года, типа "2013:"
m.a = AT("(", m.x) && содержимое в () - это название праздника
m.b = RAT(")", m.x)
m.c = AT(":", m.x) && в начале строки м.б. указание на смену умолчательного года
IF m.c>0 .AND. (m.a=0 .OR. m.c<m.a) && задана смена умолчательного года
m.y = INT(VAL(LEFT(m.x, m.c-1)))
m.x = ALLTRIM(SUBSTR(m.x, m.c+1))
LOOP
ENDIF
EXIT
ENDDO && отрезали слева указания о смене умолчательного года, типа "2013:"
IF m.a>0 .AND. m.a>m.b
m.n = ALLTRIM(SUBSTR(m.x, m.a+1, m.b-m.a-1))
m.x = ALLTRIM(LEFT(m.x, m.a-1))
ENDIF
m.a = ALLTRIM(GETWORDNUM(m.x,1,".")) && собственно ДДММГГГГ (или указатель года, например "2013:")
m.b = ALLTRIM(GETWORDNUM(m.x,2,".")) && количество нерабочих дней (умолчание - 1)
IF EMPTY(m.a)
LOOP
ENDIF
IF LEN(m.a)<5 && 5 знаков и больше, значит уже с указанием года. 4 знака или меньше - значит для умолчательного года (2 последних знака - это месяц)
m.a = m.a + ALLTRIM(STR(m.y))
ENDIF
m.t = ICASE(LEN(m.a)=8, VALTOTIP(m.a, "ДДММГГГГ"),; && попытка интерпретировать C/N-значение как дату [Д]ДММГГ[ГГ]
LEN(m.a)=7, VALTOTIP(m.a, "ДММГГГГ"),;
LEN(m.a)=6, VALTOTIP(m.a, "ДДММГГ"),;
LEN(m.a)=5, VALTOTIP(m.a, "ДММГГ"),;
{})
IF EMPTY(m.t)
LOOP
ENDIF
m.h = INT(IIF(EMPTY(m.b), 1, MAX(0, VAL(m.b)))) && кол. дополнительных нерабочих дней
IF m.h<=0
LOOP
ENDIF
m.x = ICASE(!BETWEEN(m.parD, m.t, m.t+m.h-1), 0,;
m.parD=m.t, 1,;
m.parD=m.t+m.h-1, 2,;
3)
IF EMPTY(m.x) && этот период не для даты измерения
LOOP
ENDIF
IF ICASE(BITTEST(m.m,3), IIF(m.h=1, m.x=1, m.x=1),; && факт начала периода
BITTEST(m.m,4), IIF(m.h=1, m.x=1, m.x=2),; && факт конца периода
.T.) && запрашивают что-то о периоде. Дата внутри периода
m.r = ICASE(BITTEST(m.m,0), m.parD-m.t+1,; && номер периода (вернем номер дня в периоде)
BITTEST(m.m,1), m.h,; && длительность периода
BITTEST(m.m,2), m.n,; && название периода
.T.) && факт начала/конца периода
ENDIF
EXIT
ENDFOR && перебирали элементы списка ДНД
ENDIF
ENDIF
CASE m.f="НПДП" && Понедельник, в случае, если Нерабочий праздничный день (НПД) попал на выходной день
IF DOW(m.parD,2)=1 && понедельник, может быть нерабочим днем, если 1-2 дня назад был НПД. Исключение: 2016.01.09(Пн) - рабочий день!
m.x = ICASE(Самовызов(m.parD-1, "НПД"), m.parD-1,; && воскресение - был праздник ?
Самовызов(m.parD-2, "НПД"), m.parD-2,; && суббота - был праздник ?
{})
IF !EMPTY(m.x) && вот в эту дату, в выходной день, был НПД, значит понедельник - нерабочий день
IF MONTH(m.x)=1 .AND. DAY(m.x)<=8 && 2017.01: исключение для длинной серии новогодних праздников - не сделали выходной-понедельник 2016.01.09
ELSE && типовой случай - праздник {X} пришелся на выходные
m.r = ICASE(BITTEST(m.m,0), Самовызов(m.x, "№НПД"),;
BITTEST(m.m,1), Самовызов(m.x, "$НПД"),;
BITTEST(m.m,2), Самовызов(m.x, "?НПД")+" (пер.)",;
.T.)
ENDIF
ENDIF
ENDIF && понедельник, может быть нерабочим днем
CASE m.f="РПЦпост" && РПЦ-посты
m.h = YTOEeasterJD(m.parD) + Самовызов(m.parD, "GDJD") && GD-дата РПЦ-пасхи на год измерения
RELEASE A
DIMENSION A[2,3]
A[1,1] = "Великий Пост (7 нед.)"
A[1,2] = m.h - 48
A[1,3] = m.h - 1
A[2,1] = "Петров пост (до 12 июля)"
A[2,2] = m.h + 57
A[2,3] = DATE(YEAR(m.parD), 7, 12)-1
FOR m.i=1 TO ALEN(A,1) && перебираем возможные РПЦ-посты
m.x = BETWEEN(m.parD,A[m.i,2],A[m.i,3]) && флаг ИЗМЕРЯЕМАЯ ДАТА НАХОДИТСЯ В ДИАПАЗОНЕ
IF ICASE(EMPTY(m.x), .F.,;
BITTEST(m.m,3), m.parD=A[m.i,2],;
BITTEST(m.m,4), m.parD=A[m.i,3],;
.T.)
m.r = ICASE(BITTEST(m.m,0), m.i,;
BITTEST(m.m,1), ALEN(A,1),;
BITTEST(m.m,2), A[m.i,1],;
.T.)
EXIT
ENDIF
ENDFOR && перебирали возможные РПЦ-посты
RELEASE A
CASE INLIST(m.f,"НПД","РПЦ12","РПЦ") && нерабочие праздничные дни, основные церковные дни, в новом стиле ("Двунадесять" праздников, другие церковные дни)
IF m.f="РПЦ"
m.h = YTOEeasterJD(m.parD) + Самовызов(m.parD, "GDJD") && GD-дата РПЦ-пасхи на год измерения
ENDIF
m.s = "" && почему-то надо, чтобы переменная была определена явно, а не в TEXT TO...
DO CASE
CASE m.f="НПД" && Нерабочими праздничными днями (НПД) в Российской Федерации являются (ММДДнаименование):
TEXT TO m.s NOSHOW PRETEXT 1+2 && 1-LTRIM, 2-LTRIM(TAB), 4-не записывать пустые строки, 8-не записывать ПФ
0101Новогодние каникулы
0102Новогодние каникулы
0103Новогодние каникулы
0104Новогодние каникулы
0105Новогодние каникулы
0106Новогодние каникулы
0107Рождество Христово
0108Новогодние каникулы
0223День защитника Отечества
0308Международный женский день
0501Праздник Весны и Труда
0509День Победы
0612День России
1104День народного единства
ENDTEXT
CASE m.f="РПЦ12" && основные церковные дни текстом, в новом стиле. Т.н. "Двунадесять" праздников
* Рождество Богородицы — 8 (21) сентября
* Воздвижение Креста Господня — 14 (27) сентября
* Введение во храм Пресвятой Богородицы — 21 ноября (4 декабря)
* Рождество Христово — 25 декабря (7 января)
* Крещение Господне — 6 (19) января
* Сретение Господне — 2 (15) февраля - Принесение во Храм младенца Христа его родителями = Рождество Христово + 40
* Благовещение Пресвятой Богородицы — 25 марта (7 апреля)
* Вход Господень в Иерусалим — воскресенье перед Пасхой — переходящий
* Вознесение Господне — 40-й день после Пасхи, всегда в четверг — переходящий
* День Святой Троицы — 50-й день после Пасхи, всегда в воскресенье — переходящий
* Преображение Господне — 6 (19) августа
* Успение Богородицы — 15 (28) августа
* ...что-то комментарии включить в строки не получилось, вроде в хелпе сказано, что после \ или \\ можно указывать... && - тоже не годится...
TEXT TO m.s NOSHOW PRETEXT 1+2
0107Рождество Христово
0119Богоявление, или Крещение Господне
0215Сретение Господне (Принесение во Храм младенца Христа)
0407Благовещение Пресвятой Богородицы
0819Преображение Господне
0828Успение Пресвятой Богородицы
0921Рождество Пресвятой Богородицы
0927Воздвижение Креста Господня
1204Введение во храм Пресвятой Богородицы
<<SUBSTR(DTOS(m.h- 7),5)>>Вход Господень в Иерусалим (Вербное воскресенье)
<<SUBSTR(DTOS(m.h+ 0),5)>>Пасха
<<SUBSTR(DTOS(m.h+39),5)>>Вознесение Господне
<<SUBSTR(DTOS(m.h+49),5)>>День Святой Троицы (Пятидесятница)
ENDTEXT
CASE m.f="РПЦ" && Другие церковные дни
TEXT TO m.s NOSHOW PRETEXT 1+2
0114Обрезание Господне (старый новый год)
1014Покров Пресвятой Богородицы
1104Казанской иконы Божьей Матери
0707Рождество Иоанна Крестителя (Иван Купала)
0911Усекновение главы Иоанна Крестителя
0712святых первоверховных апостолов Петра и Павла
0521святого апостола Иоанна Богослова
1009святого апостола Иоанна Богослова
0522святого чудотворца Николая (Угодника)
1219святого чудотворца Николая (Угодника)
0802Ильин день
0807Успение праведной Анны, матери Богородицы
0930День святых мучениц Веры, Надежды, Любови и матери их Софии
1104День Казанской иконы Божией Матери
0125День святой мученицы Татианы
<<SUBSTR(DTOS(m.h-49),5)>>Прощеное воскресенье
<<SUBSTR(DTOS(m.h+ 9),5)>>Радоница (Пасха для усопших)
ENDTEXT
OTHERWISE
ERROR "Неверная мода: "+m.f
ENDCASE
m.x = SUBSTR(DTOS(m.parD),5) && измеряемая дата ММДД
m.x = AT(m.x, m.s)
IF m.x>0 && есть какой-то день из списка
m.i = 1 + OCCURS(CHR(13), LEFT(m.s,m.x)) && номер вхождения в список (номер ни о чем не говорит)
m.r = ICASE(BITTEST(m.m,0), m.i,;
BITTEST(m.m,1), 1+OCCURS(CHR(13),m.s),;
BITTEST(m.m,2), GETWORDNUM(SUBSTR(m.s,m.x+4), 1, CHR(13)+CHR(10)),;
.T.)
ENDIF
CASE INLIST(m.f, "GDJD", "JD", "JDJD") && перевод JD (Юл. даты, "старый стиль") в GD (Гр., современный календарь)
m.a = YEAR(m.parD)
m.b = MONTH(m.parD)
m.c = DAY(m.parD)
m.x = INT((14-m.b)/12)
m.a = m.a + 4800 - m.x && число лет от начала календаря
m.b = m.b + 12*m.x - 3 && условный месяц
m.s = 365*m.a + INT((153*m.b+2)/5) + m.c + INT(m.a/4) - 32083 && Номер дня от начала календаря (ок 4800 до н.э.) - Общая часть для обоих календарей (GD и JD)
m.x = INT(m.a/100) - INT(m.a/400) - 38 && поправка, введенная в современном (GD) календаре, сейчас =13
m.r = ICASE(m.f="JDJD", m.s,; && Юлианская JD-дата для JD-даты юлианского календаря
m.f="JD", m.s - m.x,; && такое число возвращает SYS(11). Юлианская JD-дата для GD-даты григорианского календаря
m.f="GDJD", m.x,; && разница между григорианским (GD, современным) и юлианским (JD, "старый стиль", Пр. церковь) календарями (сейчас GD-JD=13)
0)
CASE m.f="Н" && неделя (считаем что неделя начинается с понедельника)
IF ICASE(BITTEST(m.m,3), DOW(m.parD,2)=1,; && понедельник - начало недели
BITTEST(m.m,4), DOW(m.parD,2)=7,; && воскресенье - конец недели
.T.)
IF BITTEST(m.m,1) && хотят узнать кол недель в году
m.x = DATE(YEAR(m.parD)+1,1,1)-1 && чтобы узнать число недель в году, измеряем номер недели на последний день года.
m.i = 0 && Бывает, что № недели последнего дня года =1, поэтому прокрутим дату немного назад
DO WHILE Самовызов(m.x-m.i, "№"+m.f)<=1 .AND. m.i<10 && ищем последний большой номер недели
m.i = m.i+1
ENDDO
m.r = Самовызов(m.x-m.i, "№"+m.f)
ELSE && хотят узнать номер недели, или др...
m.r = WEEK(m.parD) && собственно номер недели в году... См. в хелп про 2й параметр ф-ии - вариант счета недель... Умолчание SET FWEEK - "Первая неделя года начинается с 1-го января"
m.r = ICASE(BITTEST(m.m,0), m.r,; && номер недели в году
BITTEST(m.m,2), TRANSFORM(m.r),; && название недели
.T.)
ENDIF
ENDIF
CASE m.f="К" && квартал
IF ICASE(BITTEST(m.m,3), DAY(m.parD)=1 .AND. INLIST(MONTH(m.parD),1,4,7,10),;
BITTEST(m.m,4), DAY(m.parD+1)=1 .AND. INLIST(MONTH(m.parD),3,6,9,12),;
.T.)
m.x = QUARTER(m.parD)
m.r = ICASE(BITTEST(m.m,0), m.x,;
BITTEST(m.m,1), 4,;
BITTEST(m.m,2), IIF(m.x=4,"IV", LEFT("III",m.x)),;
.T.)
ENDIF
CASE m.f="ПГ" && полугодие
IF ICASE(BITTEST(m.m,3), DAY(m.parD)=1 .AND. INLIST(MONTH(m.parD),1,6),;
BITTEST(m.m,4), DAY(m.parD+1)=1 .AND. INLIST(MONTH(m.parD),5,12),;
.T.)
m.x = ICASE(MONTH(m.parD)>=6, 2, MONTH(m.parD)>=1, 1, 0)
m.r = ICASE(BITTEST(m.m,0), m.x,;
BITTEST(m.m,1), 2,;
BITTEST(m.m,2), LEFT("II", m.x),;
.T.)
ENDIF
OTHERWISE
ERROR "Неверный период: "+TRANSFORM(m.parN1)
ENDCASE
RETURN m.r
ENDCASE
RETURN 0 && IsLimDate
#UNDEFINE Самовызов


Доб. Штатнее выходные дни прога знает. Вышестояший спич был о внештатных вых. днях. Он вносит проблы в счет ... всяких расчетов ЗП, вы в курсе, дб....



Исправлено 3 раз(а). Последнее : of63, 15.02.23 02:04
Ratings: 0 negative/0 positive
Re: Список месяцев
AndyNigmatec

Сообщений: 1573
Откуда: Волгоград
Дата регистрации: 28.06.2015
Я для себя не видел никакого смысла делить выхи на штатные/нештаные ... заполнил таблицу - и спокойно обычными запросами без разных "мегафункций" пользую.
Мало того, иногда начальству (хз зачем) требуется посчитать прогноз как если бы вот этот день был рабочим - и вуаля, поменял один признак - посчитал и поменял взад, а в случае с функцией это еще та задачка бы была )))
Ratings: 0 negative/0 positive
Re: Список месяцев
Владимир Максимов

Сообщений: 14098
Откуда: Москва
Дата регистрации: 02.09.2000
Календарь - это не нечто "в неком файле старта". Это обычный справочник, каких много в любом приложении. Точно такой же, как справочник номенклатур или клиентов/поставщиков. Со своей спецификой, конечно, но именно что "справочник"

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

Наверное, все-таки надо пояснить.

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

Вышло постановление о выходных днях - пользователь открыл форму календаря и завел соответствующие даты или расставил галки. Тут уж как именно этот справочник реализован.
Ratings: 0 negative/0 positive


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

On-line: 5 (Гостей: 5)

© 2000-2024 Fox Club 
Яндекс.Метрика