Всем добрый день!
Прошу помощи, так как только начала работать в области разработки/программирования в 1С.
Пишу конфигурацию для проходной с нуля, есть документ в который вносится дата и время въезда и выезда Нужно, чтобы при определенном времени заезда/выезда количество дней и ночей проведенных на стоянке помещались в соответствующие поля.
Например:
Нахождение на территории в период с 08.00 до 20.00 - считается как 1 день, с 20.01 до 07.59 - считается как 1 ночь. При вводе данных о въезде 15.02.2024 08.00 и выезде 16.02.2024 23.00. в поле количество дней соответственно должно попасть - 2 дня, в поле количество ночей - 2 ночи.
Заранее спасибо!
---
Делайте, как вам сейчас проще, не гонитесь за красивым кодом. Да, мы получили дневное время. Если ВремяВъезда между этими периодами, то заехал днем, иначе - ночью. Ночи тоже могут быть, как предыдущая, так и следующая по суткам. Тут уж сами определитесь, как это учесть.
Теперь можно от даты выезда отнять дату въезда и получить количество секунд, которые преобразуем в полные сутки (день+ночь). Останется только проверить дату выезда, когда она произошла: днем или ночью.
---
В итоге получилось благодаря помощи LexaK с форума База таким образом:
&НаКлиенте
Процедура ВремяВыездаПриИзменении(Элемент)
П1 = 0;
П2 = 0;
Объект.КолвоДней = 0;
Объект.КолвоНочей = 0;
ДатаВъезд = Формат (Объект.ДатаВъезда, "ДФ=""ггггММдд""");
ВремяВъезд = Формат (Объект.ВремяВъезда, "ДФ=""ЧЧмм""");
Дата1 = Дата (ДатаВъезд + ВремяВъезд);
ДатаВыезд = Формат (Объект.ДатаВыезда, "ДФ=""ггггММдд""");
ВремяВыезд = Формат (Объект.ВремяВыезда, "ДФ=""ЧЧмм""");
Дата2 = Дата (ДатаВыезд + ВремяВыезд);
ЭтоДень = Ложь;
Пока П1 = 0 или Дата2 > П2 Цикл
Если П1 = 0 Тогда
П1 = НачалоДня (Дата1);
П2 = П1 + 8 * 3600;
ЭтоДень = Ложь;
Если Дата1 < П2 Тогда
Иначе
Продолжить;
КонецЕсли;
Иначе
П1 = П2;
П2 = П1 + 12 * 3600;
ЭтоДень = Не ЭтоДень;
Если Дата1 > П2 Тогда
Продолжить;
КонецЕсли;
КонецЕсли;

Если ЭтоДень Тогда
Объект.КолвоДней = Объект.КолвоДней + 1;
Иначе
Объект.КолвоНочей = Объект.КолвоНочей + 1;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
---
Обнаружила, что при вводе времени выезда раньше, чем время въезда в количество дней/ночей все равно считает и пишет как 1. Поправила код:

```1c
    &НаКлиенте
    Процедура ВремяВыездаПриИзменении(Элемент)
    П1 = 0;
    П2 = 0;
    Объект.КолвоДней = 0;
    Объект.КолвоНочей = 0;
    ДатаВъезд = Формат (Объект.ДатаВъезда, "ДФ="ггггММдд"");
    ВремяВъезд = Формат (Объект.ВремяВъезда, "ДФ="ЧЧмм"");
    Въезд = Дата (ДатаВъезд + ВремяВъезд);
    ДатаВыезд = Формат (Объект.ДатаВыезда, "ДФ="ггггММдд"");
    ВремяВыезд = Формат (Объект.ВремяВыезда, "ДФ="ЧЧмм"");
    Выезд = Дата (ДатаВыезд + ВремяВыезд);
    ЭтоДень = Ложь;

    Пока П1 = 0 или Выезд > П2 Цикл
    Если П1 = 0 Тогда
    П1 = НачалоДня (Въезд);

    П2 = П1 + 8 * 3599;
    ЭтоДень = Ложь;
    Если Въезд < П2 Тогда
    Иначе
    Продолжить;
    КонецЕсли;
    Иначе
    П1 = П2;

    П2 = П1 + 12 * 3601;
    ЭтоДень = Не ЭтоДень;
    Если Въезд > П2 Тогда
    Продолжить;
    КонецЕсли;
    КонецЕсли;

    Если Выезд < Въезд Тогда
    Объект.КолвоДней = 0
    Иначе
    Если ЭтоДень Тогда
    Объект.КолвоДней = Объект.КолвоДней + 1;
    Иначе
    Объект.КолвоНочей = Объект.КолвоНочей + 1;
    КонецЕсли;
    КонецЕсли;
    КонецЦикла;

    Если Выезд < Въезд Тогда
    Сообщить ("Время выезда не может быть раньше время въезда. Исправьте время!");
    КонецЕсли;
```
---
Вообще не проблема:

```1c
    НульДата=Дата(1,1,1,0,0,0);
    Объект.КоличествоДней=0;
    Объект.КоличествоНочей=0;
    ДатаВъезда=Объект.ДатаВъезда+(Объект.ВремяВъезда-Нульдата);
    ДатаВыезда=Объект.ДатаВыезда+(Объект.ВремяВыезда-Нульдата);
    Если ДатаВыезда<ДатаВъезда Тогда
    Возврат;
    КонецЕсли;
    ЗаехалДнем=?(Час(ДатаВъезда)>=8 И Час(ДатаВъезда)<20,1,0);
    ВыехалДнем=?(Час(ДатаВыезда)>=8 И Час(ДатаВыезда)<20,1,0);
    ВъездВыездНочью=?(Час(ДатаВъезда)<8 И Час(ДатаВыезда)>=20,1,0);
    ВремяСекунд=ДатаВыезда-ДатаВъезда;
    ЧислоПериодов=Цел(ВремяСекунд/(60*60*12));
    Объект.КоличествоДней=Цел(ЧислоПериодов/2)+ЗаехалДнем;
    Объект.КоличествоНочей=Цел(ЧислоПериодов/2)+(1-ЗаехалДнем);
    Если (ЗаехалДнем<>ВыехалДнем) Или ВъездВыездНочью=1 Или (НЕ ЧислоПериодов%2=0) Тогда
    Объект.КоличествоДней=Объект.КоличествоДней+ВыехалДнем+ВъездВыездНочью;
    Объект.КоличествоНочей=Объект.КоличествоНочей+(1-ВыехалДнем);
    КонецЕсли;
```
---
т.е. азы программирования 1С вы не знаете, синтаксис-помощник по операциям со значением типа "дата" читать так же не хотите, но хотите, что бы за вас поработали?
---
Как раз только азы я и знаю. Я понимаю, что это должно быть скорее всего через Если, Цикл, возможно нужно будет поместить результат в Массив чтобы там считалось количество (хотя может и это я не правильно представляю), но как это реализовать, пока к сожалению не понимаю.
---
8-( * )

1С умеет математические операции(сложение/вычитание) со значениями типа "дата" делать.
Тут решение вида

```1c
    В = А + Б
```

, а вы какие-то Если, Циклы и, упасихоспади, Массивы применять собрались. Вы еще запрос используйте для решения, ну а почему бы и нет :)
---
ну А и Б то откуда то должно взяться... О запросе тоже была мысль, но подумала, что это уже слишком :-D
---
вы их уже на форме разместили, пользователь в них введет нужные ему данные
если не введет, будут "пустые" значения, но они так же поддаются математическим действиям с ними
---
В том то и дело, что поля количество дней и ночей должны автоматом считаться на основании введенных дат и времени. Поля продолжительности стоянки не доступны для редактирования.
---
в чем сложность присвоить значения соответствующим реквизитам(объекта/формы) в соответствующих обработчиках событий элементов формы "ПриИзменении"?

У вас
входные переменные: ДатаВъезда, ВремяВъезда, ДатаВыезда, ВремяВыезда
выходные переменные: КоличествоНочей, КоличествоДней

Что мешает сделать простые математические операции между входными переменными и присвоить значения в выходные переменные?

Да, придется проверить равенство дат, т.е. использовать таки одно Если :)
---
Ну вот, все таки без Если не обойтись, а я со вчерашнего дня и так и сяк и наперекосяк и ничего не получается.. )))
---
Приведите текст своего кода, и мы поможем разобраться с текстом запроса, логарифмами и котангенсами.
---
Последний раз был такой вариант, но это даже кодом стыдно назвать...

```1c
    &НаКлиенте
    Процедура ВремяВыездаПриИзменении(Элемент)
    А = Объект.ДатаВъезда + Объект.ВремяВъезда>"07:59";
    Б = Объект.ДатаВыезда + Объект.ВремяВыезда<"19:59";
    В = Б-А;
    Объект.КолвоДней = Число (В);
    КонецПроцедуры
```
---
Ой.
Попробуем начать с простого.

```1c
    НачВремяДня=НачалоДня(Объект.ВремяВъезда)+8*60*60;
    НачВремяНочи=НачалоДня(Объект.ВремяВъезда)+20*60*60;
```

Можно и другими способами получить, но тут видно, что время состоит из секунд.
---
сама понимаю, что ой...
Тут мы определили ночные и дневные периоды, правильно я понимаю?
Я кстати думала, что это надо будет определять через Если..
---
Делайте, как вам сейчас проще, не гонитесь за красивым кодом. Да, мы получили дневное время. Если ВремяВъезда между этими периодами, то заехал днем, иначе - ночью. Ночи тоже могут быть, как предыдущая, так и следующая по суткам. Тут уж сами определитесь, как это учесть.
Теперь можно от даты выезда отнять дату въезда и получить количество секунд, которые преобразуем в полные сутки (день+ночь). Останется только проверить дату выезда, когда она произошла: днем или ночью.
---
Правильно я понимаю, что все это я делаю в процедуре при изменении время выезда?
---
Да как угодно можно. Можно отдельную команду использовать с кнопкой, можно при любом изменении данных пересчитывать. Делайте отдельной процедурой, к которой будете обращаться по мере необходимости.
---
Просто при создании на сервере?
---
Отвечу вопросом на вопрос. Открыли вы на сервере документ, и что собираетесь считать, если реквизиты не заполнены?
---
Значит тогда логичнее все таки в процедуре при изменении время выезда.
Спасибо Вам большое за терпение и разъяснения!
Просто на словах, я все это понимаю, а как написать код, да еще и чтоб он работал...
---
В итоге получилось благодаря помощи LexaK с форума База таким образом:
&НаКлиенте
Процедура ВремяВыездаПриИзменении(Элемент)
П1 = 0;
П2 = 0;
Объект.КолвоДней = 0;
Объект.КолвоНочей = 0;
ДатаВъезд = Формат (Объект.ДатаВъезда, "ДФ=""ггггММдд""");
ВремяВъезд = Формат (Объект.ВремяВъезда, "ДФ=""ЧЧмм""");
Дата1 = Дата (ДатаВъезд + ВремяВъезд);
ДатаВыезд = Формат (Объект.ДатаВыезда, "ДФ=""ггггММдд""");
ВремяВыезд = Формат (Объект.ВремяВыезда, "ДФ=""ЧЧмм""");
Дата2 = Дата (ДатаВыезд + ВремяВыезд);
ЭтоДень = Ложь;
Пока П1 = 0 или Дата2 > П2 Цикл
Если П1 = 0 Тогда
П1 = НачалоДня (Дата1);
П2 = П1 + 8 * 3600;
ЭтоДень = Ложь;
Если Дата1 < П2 Тогда
Иначе
Продолжить;
КонецЕсли;
Иначе
П1 = П2;
П2 = П1 + 12 * 3600;
ЭтоДень = Не ЭтоДень;
Если Дата1 > П2 Тогда
Продолжить;
КонецЕсли;
КонецЕсли;

Если ЭтоДень Тогда
Объект.КолвоДней = Объект.КолвоДней + 1;
Иначе
Объект.КолвоНочей = Объект.КолвоНочей + 1;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
---
Точно все проверили?
---
Если нужно, чтобы минуты не пересекались, необходимо заменить 3600 на 3599 и 3600 на 3601 тогда будет считать, ночь с 20.01 по 07.59 и день с 08.00 по 20.00.
Спасибо Вам большое Vlan!
---
У меня вот такой вариант получился:

```1c
    Объект.КоличествоДней=0;
    Объект.КоличествоНочей=0;
    Если Объект.ДатаВыезда<Объект.ДатаВъезда Тогда
    Возврат;
    КонецЕсли;
    ЗаехалДнем=Час(Объект.ДатаВъезда)>=8 И Час(Объект.ДатаВъезда)<20;
    ВыехалДнем=Час(Объект.ДатаВыезда)>=8 И Час(Объект.ДатаВыезда)<20;
    ВъездВыездНочью=Час(Объект.ДатаВъезда)<8 И Час(Объект.ДатаВыезда)>=20;
    ВремяСекунд=Объект.ДатаВыезда-Объект.ДатаВъезда;
    ЧислоПериодов=Цел(ВремяСекунд/(60*60*12));
    Объект.КоличествоДней=Цел(ЧислоПериодов/2)+ЗаехалДнем;
    Объект.КоличествоНочей=Цел(ЧислоПериодов/2)+(Не ЗаехалДнем);
    Если (ЗаехалДнем<>ВыехалДнем) Или ВъездВыездНочью Или (НЕ ЧислоПериодов%2=0) Тогда
    Объект.КоличествоДней=Объект.КоличествоДней+ВыехалДнем+ВъездВыездНочью;
    Объект.КоличествоНочей=Объект.КоличествоНочей+(Не ВыехалДнем);
    КонецЕсли;
```
---
я проверила Ваш код, он почему то считает только количество ночей..
---
Странно. Я, конечно, скурпулезно не проверял, но подкидывал разные варианты, и все считалось верно. У вас, скорее всего, что-то со временем не так было. Еще допускаю разночтение из-за "недокументированного" использования преобразования булево в число. Можно попробовать такой вариант, более корректный.

```1c
    Объект.КоличествоДней=0;
    Объект.КоличествоНочей=0;
    Если Объект.ДатаВыезда<Объект.ДатаВъезда Тогда
    Возврат;
    КонецЕсли;
    ЗаехалДнем=?(Час(Объект.ДатаВъезда)>=8 И Час(Объект.ДатаВъезда)<20,1,0);
    ВыехалДнем=?(Час(Объект.ДатаВыезда)>=8 И Час(Объект.ДатаВыезда)<20,1,0);
    ВъездВыездНочью=?(Час(Объект.ДатаВъезда)<8 И Час(Объект.ДатаВыезда)>=20,1,0);
    ВремяСекунд=Объект.ДатаВыезда-Объект.ДатаВъезда;
    ЧислоПериодов=Цел(ВремяСекунд/(60*60*12));
    Объект.КоличествоДней=Цел(ЧислоПериодов/2)+ЗаехалДнем;
    Объект.КоличествоНочей=Цел(ЧислоПериодов/2)+(1-ЗаехалДнем);
    Если (ЗаехалДнем<>ВыехалДнем) Или ВъездВыездНочью=1 Или (НЕ ЧислоПериодов%2=0) Тогда
    Объект.КоличествоДней=Объект.КоличествоДней+ВыехалДнем+ВъездВыездНочью;
    Объект.КоличествоНочей=Объект.КоличествоНочей+(1-ВыехалДнем);
    КонецЕсли;
```

Если и тут будет ошибка, то напишите исходные данные, при которой она возникает, проверю.
---
Объект.КоличествоДней=0;
    Объект.КоличествоНочей=0;
    Если Объект.ДатаВыезда=8 И Час(Объект.ДатаВъезда)=8 И Час(Объект.ДатаВыезда)=20,1,0);
    ВремяСекунд=Объект.ДатаВыезда-Объект.ДатаВъезда;
    ЧислоПериодов=Цел(ВремяСекунд/(60*60*12));
    Объект.КоличествоДней=Цел(ЧислоПериодов/2)+ЗаехалДнем;
    Объект.КоличествоНочей=Цел(ЧислоПериодов/2)+(1-ЗаехалДнем);
    Если (ЗаехалДнем<>ВыехалДнем) Или ВъездВыездНочью=1 Или (НЕ ЧислоПериодов%2=0) Тогда
        Объект.КоличествоДней=Объект.КоличествоДней+ВыехалДнем+ВъездВыездНочью;
        Объект.КоличествоНочей=Объект.КоличествоНочей+(1-ВыехалДнем);
    КонецЕсли;

Он почему то помещает данные после счета только в количество ночей, дни считает, только если ввести другой день и то не правильно
---
Когда время присоединяете, посмотрите, что у вас за даты получаются. Должна быть стандартная дата со временем, а не текст.
---
Обнаружила, что при вводе времени выезда раньше, чем время въезда в количество дней/ночей все равно считает и пишет как 1. Поправила код:

```1c
    &НаКлиенте
    Процедура ВремяВыездаПриИзменении(Элемент)
    П1 = 0;
    П2 = 0;
    Объект.КолвоДней = 0;
    Объект.КолвоНочей = 0;
    ДатаВъезд = Формат (Объект.ДатаВъезда, "ДФ="ггггММдд"");
    ВремяВъезд = Формат (Объект.ВремяВъезда, "ДФ="ЧЧмм"");
    Въезд = Дата (ДатаВъезд + ВремяВъезд);
    ДатаВыезд = Формат (Объект.ДатаВыезда, "ДФ="ггггММдд"");
    ВремяВыезд = Формат (Объект.ВремяВыезда, "ДФ="ЧЧмм"");
    Выезд = Дата (ДатаВыезд + ВремяВыезд);
    ЭтоДень = Ложь;

    Пока П1 = 0 или Выезд > П2 Цикл
    Если П1 = 0 Тогда
    П1 = НачалоДня (Въезд);

    П2 = П1 + 8 * 3599;
    ЭтоДень = Ложь;
    Если Въезд < П2 Тогда
    Иначе
    Продолжить;
    КонецЕсли;
    Иначе
    П1 = П2;

    П2 = П1 + 12 * 3601;
    ЭтоДень = Не ЭтоДень;
    Если Въезд > П2 Тогда
    Продолжить;
    КонецЕсли;
    КонецЕсли;

    Если Выезд < Въезд Тогда
    Объект.КолвоДней = 0
    Иначе
    Если ЭтоДень Тогда
    Объект.КолвоДней = Объект.КолвоДней + 1;
    Иначе
    Объект.КолвоНочей = Объект.КолвоНочей + 1;
    КонецЕсли;
    КонецЕсли;
    КонецЦикла;

    Если Выезд < Въезд Тогда
    Сообщить ("Время выезда не может быть раньше время въезда. Исправьте время!");
    КонецЕсли;
```
---
Дело в том, что по заданию, должны быть отдельные поля с датой и временем. И поля соответственно у меня с форматом даты, просто одно только дата, другое только время.
---
Вообще не проблема:

```1c
    НульДата=Дата(1,1,1,0,0,0);
    Объект.КоличествоДней=0;
    Объект.КоличествоНочей=0;
    ДатаВъезда=Объект.ДатаВъезда+(Объект.ВремяВъезда-Нульдата);
    ДатаВыезда=Объект.ДатаВыезда+(Объект.ВремяВыезда-Нульдата);
    Если ДатаВыезда<ДатаВъезда Тогда
    Возврат;
    КонецЕсли;
    ЗаехалДнем=?(Час(ДатаВъезда)>=8 И Час(ДатаВъезда)<20,1,0);
    ВыехалДнем=?(Час(ДатаВыезда)>=8 И Час(ДатаВыезда)<20,1,0);
    ВъездВыездНочью=?(Час(ДатаВъезда)<8 И Час(ДатаВыезда)>=20,1,0);
    ВремяСекунд=ДатаВыезда-ДатаВъезда;
    ЧислоПериодов=Цел(ВремяСекунд/(60*60*12));
    Объект.КоличествоДней=Цел(ЧислоПериодов/2)+ЗаехалДнем;
    Объект.КоличествоНочей=Цел(ЧислоПериодов/2)+(1-ЗаехалДнем);
    Если (ЗаехалДнем<>ВыехалДнем) Или ВъездВыездНочью=1 Или (НЕ ЧислоПериодов%2=0) Тогда
    Объект.КоличествоДней=Объект.КоличествоДней+ВыехалДнем+ВъездВыездНочью;
    Объект.КоличествоНочей=Объект.КоличествоНочей+(1-ВыехалДнем);
    КонецЕсли;
```
---
Теперь все работает.