Подсчет данных из двух полей и помещение результата в другое

1. DKNY_ 15.02.24 14:51 Сейчас в теме
Всем добрый день!
Прошу помощи, так как только начала работать в области разработки/программирования в 1С.
Пишу конфигурацию для проходной с нуля, есть документ в который вносится дата и время въезда и выезда Нужно, чтобы при определенном времени заезда/выезда количество дней и ночей проведенных на стоянке помещались в соответствующие поля.
Например:
Нахождение на территории в период с 08.00 до 20.00 - считается как 1 день, с 20.01 до 07.59 - считается как 1 ночь. При вводе данных о въезде 15.02.2024 08.00 и выезде 16.02.2024 23.00. в поле количество дней соответственно должно попасть - 2 дня, в поле количество ночей - 2 ночи.
Заранее спасибо!
Прикрепленные файлы:
По теме из базы знаний
Найденные решения
14. Vlan 36 16.02.24 12:03 Сейчас в теме
(13) Делайте, как вам сейчас проще, не гонитесь за красивым кодом. Да, мы получили дневное время. Если ВремяВъезда между этими периодами, то заехал днем, иначе - ночью. Ночи тоже могут быть, как предыдущая, так и следующая по суткам. Тут уж сами определитесь, как это учесть.
Теперь можно от даты выезда отнять дату въезда и получить количество секунд, которые преобразуем в полные сутки (день+ночь). Останется только проверить дату выезда, когда она произошла: днем или ночью.
20. DKNY_ 27.02.24 10:53 Сейчас в теме
В итоге получилось благодаря помощи 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;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
24. DKNY_ 11.03.24 17:01 Сейчас в теме
Обнаружила, что при вводе времени выезда раньше, чем время въезда в количество дней/ночей все равно считает и пишет как 1. Поправила код:
&НаКлиенте
Процедура ВремяВыездаПриИзменении(Элемент)
	П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;
				КонецЕсли;
			КонецЕсли;
	КонецЦикла;
	
	Если Выезд < Въезд Тогда
		Сообщить ("Время выезда не может быть раньше время въезда. Исправьте время!");
	КонецЕсли;
Показать
30. Vlan 36 12.03.24 13:32 Сейчас в теме
(29) Вообще не проблема:

	НульДата=Дата(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-ВыехалДнем);
	КонецЕсли;
Показать
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. nomad_irk 76 15.02.24 15:01 Сейчас в теме
(1)т.е. азы программирования 1С вы не знаете, синтаксис-помощник по операциям со значением типа "дата" читать так же не хотите, но хотите, что бы за вас поработали?
3. DKNY_ 15.02.24 15:09 Сейчас в теме
(2) Как раз только азы я и знаю. Я понимаю, что это должно быть скорее всего через Если, Цикл, возможно нужно будет поместить результат в Массив чтобы там считалось количество (хотя может и это я не правильно представляю), но как это реализовать, пока к сожалению не понимаю.
4. nomad_irk 76 15.02.24 15:23 Сейчас в теме
(3)8-( * )

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

, а вы какие-то Если, Циклы и, упасихоспади, Массивы применять собрались. Вы еще запрос используйте для решения, ну а почему бы и нет :)
5. DKNY_ 15.02.24 15:29 Сейчас в теме
(4) ну А и Б то откуда то должно взяться... О запросе тоже была мысль, но подумала, что это уже слишком :-D
6. nomad_irk 76 15.02.24 15:30 Сейчас в теме
(5)вы их уже на форме разместили, пользователь в них введет нужные ему данные
если не введет, будут "пустые" значения, но они так же поддаются математическим действиям с ними
7. DKNY_ 15.02.24 15:32 Сейчас в теме
(6) В том то и дело, что поля количество дней и ночей должны автоматом считаться на основании введенных дат и времени. Поля продолжительности стоянки не доступны для редактирования.
8. nomad_irk 76 15.02.24 15:35 Сейчас в теме
(7)в чем сложность присвоить значения соответствующим реквизитам(объекта/формы) в соответствующих обработчиках событий элементов формы "ПриИзменении"?

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

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

Да, придется проверить равенство дат, т.е. использовать таки одно Если :)
9. DKNY_ 16.02.24 09:38 Сейчас в теме
(8) Ну вот, все таки без Если не обойтись, а я со вчерашнего дня и так и сяк и наперекосяк и ничего не получается.. )))
10. Vlan 36 16.02.24 10:25 Сейчас в теме
(9) Приведите текст своего кода, и мы поможем разобраться с текстом запроса, логарифмами и котангенсами.
11. DKNY_ 16.02.24 10:44 Сейчас в теме
(10) Последний раз был такой вариант, но это даже кодом стыдно назвать...

&НаКлиенте
Процедура ВремяВыездаПриИзменении(Элемент)
	А = Объект.ДатаВъезда + Объект.ВремяВъезда>"07:59";
	Б = Объект.ДатаВыезда + Объект.ВремяВыезда<"19:59";
	В = Б-А;
	Объект.КолвоДней = Число (В);
КонецПроцедуры
12. Vlan 36 16.02.24 11:15 Сейчас в теме
(11) Ой.
Попробуем начать с простого.
НачВремяДня=НачалоДня(Объект.ВремяВъезда)+8*60*60;
НачВремяНочи=НачалоДня(Объект.ВремяВъезда)+20*60*60;


Можно и другими способами получить, но тут видно, что время состоит из секунд.
13. DKNY_ 16.02.24 11:24 Сейчас в теме
(12) сама понимаю, что ой...
Тут мы определили ночные и дневные периоды, правильно я понимаю?
Я кстати думала, что это надо будет определять через Если..
14. Vlan 36 16.02.24 12:03 Сейчас в теме
(13) Делайте, как вам сейчас проще, не гонитесь за красивым кодом. Да, мы получили дневное время. Если ВремяВъезда между этими периодами, то заехал днем, иначе - ночью. Ночи тоже могут быть, как предыдущая, так и следующая по суткам. Тут уж сами определитесь, как это учесть.
Теперь можно от даты выезда отнять дату въезда и получить количество секунд, которые преобразуем в полные сутки (день+ночь). Останется только проверить дату выезда, когда она произошла: днем или ночью.
15. DKNY_ 16.02.24 12:42 Сейчас в теме
(14) Правильно я понимаю, что все это я делаю в процедуре при изменении время выезда?
16. Vlan 36 16.02.24 12:51 Сейчас в теме
(15) Да как угодно можно. Можно отдельную команду использовать с кнопкой, можно при любом изменении данных пересчитывать. Делайте отдельной процедурой, к которой будете обращаться по мере необходимости.
17. DKNY_ 16.02.24 12:53 Сейчас в теме
(16) Просто при создании на сервере?
18. Vlan 36 16.02.24 13:52 Сейчас в теме
(17) Отвечу вопросом на вопрос. Открыли вы на сервере документ, и что собираетесь считать, если реквизиты не заполнены?
19. DKNY_ 16.02.24 13:55 Сейчас в теме
(18) Значит тогда логичнее все таки в процедуре при изменении время выезда.
Спасибо Вам большое за терпение и разъяснения!
Просто на словах, я все это понимаю, а как написать код, да еще и чтоб он работал...
20. DKNY_ 27.02.24 10:53 Сейчас в теме
В итоге получилось благодаря помощи 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;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
21. Vlan 36 28.02.24 11:53 Сейчас в теме
22. DKNY_ 01.03.24 12:49 Сейчас в теме
Если нужно, чтобы минуты не пересекались, необходимо заменить 3600 на 3599 и 3600 на 3601 тогда будет считать, ночь с 20.01 по 07.59 и день с 08.00 по 20.00.
Спасибо Вам большое Vlan!
23. Vlan 36 05.03.24 08:56 Сейчас в теме
У меня вот такой вариант получился:
	Объект.КоличествоДней=0;
	Объект.КоличествоНочей=0;
	Если Объект.ДатаВыезда<Объект.ДатаВъезда Тогда
		Возврат;
	КонецЕсли;
	ЗаехалДнем=Час(Объект.ДатаВъезда)>=8 И Час(Объект.ДатаВъезда)<20;
	ВыехалДнем=Час(Объект.ДатаВыезда)>=8 И Час(Объект.ДатаВыезда)<20;
	ВъездВыездНочью=Час(Объект.ДатаВъезда)<8 И Час(Объект.ДатаВыезда)>=20;
	ВремяСекунд=Объект.ДатаВыезда-Объект.ДатаВъезда;
	ЧислоПериодов=Цел(ВремяСекунд/(60*60*12));
	Объект.КоличествоДней=Цел(ЧислоПериодов/2)+ЗаехалДнем;
	Объект.КоличествоНочей=Цел(ЧислоПериодов/2)+(Не ЗаехалДнем);
	Если (ЗаехалДнем<>ВыехалДнем) Или ВъездВыездНочью Или (НЕ ЧислоПериодов%2=0) Тогда
		Объект.КоличествоДней=Объект.КоличествоДней+ВыехалДнем+ВъездВыездНочью;
		Объект.КоличествоНочей=Объект.КоличествоНочей+(Не ВыехалДнем);
	КонецЕсли;
Показать
25. DKNY_ 11.03.24 17:36 Сейчас в теме
(23) я проверила Ваш код, он почему то считает только количество ночей..
26. Vlan 36 12.03.24 06:45 Сейчас в теме
(25) Странно. Я, конечно, скурпулезно не проверял, но подкидывал разные варианты, и все считалось верно. У вас, скорее всего, что-то со временем не так было. Еще допускаю разночтение из-за "недокументированного" использования преобразования булево в число. Можно попробовать такой вариант, более корректный.
	Объект.КоличествоДней=0;
	Объект.КоличествоНочей=0;
	Если Объект.ДатаВыезда<Объект.ДатаВъезда Тогда
		Возврат;
	КонецЕсли;
	ЗаехалДнем=?(Час(Объект.ДатаВъезда)>=8 И Час(Объект.ДатаВъезда)<20,1,0);
	ВыехалДнем=?(Час(Объект.ДатаВыезда)>=8 И Час(Объект.ДатаВыезда)<20,1,0);
	ВъездВыездНочью=?(Час(Объект.ДатаВъезда)<8 И Час(Объект.ДатаВыезда)>=20,1,0);
	ВремяСекунд=Объект.ДатаВыезда-Объект.ДатаВъезда;
	ЧислоПериодов=Цел(ВремяСекунд/(60*60*12));
	Объект.КоличествоДней=Цел(ЧислоПериодов/2)+ЗаехалДнем;
	Объект.КоличествоНочей=Цел(ЧислоПериодов/2)+(1-ЗаехалДнем);
	Если (ЗаехалДнем<>ВыехалДнем) Или ВъездВыездНочью=1 Или (НЕ ЧислоПериодов%2=0) Тогда
		Объект.КоличествоДней=Объект.КоличествоДней+ВыехалДнем+ВъездВыездНочью;
		Объект.КоличествоНочей=Объект.КоличествоНочей+(1-ВыехалДнем);
	КонецЕсли;
Показать

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


Он почему то помещает данные после счета только в количество ночей, дни считает, только если ввести другой день и то не правильно
Прикрепленные файлы:
28. Vlan 36 12.03.24 10:56 Сейчас в теме
(27) Когда время присоединяете, посмотрите, что у вас за даты получаются. Должна быть стандартная дата со временем, а не текст.
Прикрепленные файлы:
24. DKNY_ 11.03.24 17:01 Сейчас в теме
Обнаружила, что при вводе времени выезда раньше, чем время въезда в количество дней/ночей все равно считает и пишет как 1. Поправила код:
&НаКлиенте
Процедура ВремяВыездаПриИзменении(Элемент)
	П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;
				КонецЕсли;
			КонецЕсли;
	КонецЦикла;
	
	Если Выезд < Въезд Тогда
		Сообщить ("Время выезда не может быть раньше время въезда. Исправьте время!");
	КонецЕсли;
Показать
29. DKNY_ 12.03.24 11:57 Сейчас в теме
(28) Дело в том, что по заданию, должны быть отдельные поля с датой и временем. И поля соответственно у меня с форматом даты, просто одно только дата, другое только время.
30. Vlan 36 12.03.24 13:32 Сейчас в теме
(29) Вообще не проблема:

	НульДата=Дата(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-ВыехалДнем);
	КонецЕсли;
Показать
31. DKNY_ 15.03.24 11:06 Сейчас в теме
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот