ОБСУЖДЕНИЕ

Проблема с получением данных из справочников

8 ответов 6,7 тыс.
AI-выжимка обсуждения скоро

Краткие тезисы обсуждения со ссылками на ключевые ответы появятся здесь.

Автор темы
Разрабатываю конфигурацию для наших медиков, почти все готово, но никак не могу наладить процедуру КонтрольТарифов. Алгоритм процедуры следующий:
пробегаю построчно документ, содержащий записи о пациентах. Имеется переменная КодПрофиля (число) и КодСпециальности (строковый код), по ним нужно определить тариф. Если переменная ВидМедицинскойПомощи равен 2, то это поликлиника и тогда смотрим справочник ТарифыПоликлиника. Там они привязаны к врачебным специальностям (есть отдельный справочник для этого). Я ищу специальность по коду (использую переменную КодСпециальности) в справочнике Врачебные Специальности (тип кода - числовой), потом беру соответствующий элемент этого справочника и по нему в справочнике ТарифыПоликлиника нахожу соответствующицй тариф. Далее вычисляю сумму за лечение (количество дней * сумму тарифа) и сравниваю с тем, что выставлено в реестре. Если несовпадение - то ошибка! Все работает правильно, вот только сами тарифы из справочников не вытягиваются. Естественно, что в таком случае у меня постоянно выскакивает, что сумма тарифа рассчитана неправильно. Пробовал разные варианты, гонял отладчиком - все впустую..

Код:
Процедура КонтрольТарифов() 
ВыбратьСтроки();
ТЗ=СоздатьОбъект("ТаблицаЗначений");
ТЗ.НоваяКолонка("Фамилия");
ТЗ.НоваяКолонка("Имя");
ТЗ.НоваяКолонка("Отчество");
ТЗ.НоваяКолонка("ДатаРождения");
ТЗ.НоваяКолонка("Пол");
ТЗ.НоваяКолонка("ПорядковыйНомер");
ТЗ.НоваяКолонка("ПроверкаТарифа"); 	

СпрСтационар = СоздатьОбъект("Справочник.ТарифыСтационар"); 
СпрПоликлиника = СоздатьОбъект("Справочник.ТарифыПоликлиника");
СпрЛПУ = СоздатьОбъект("Справочник.Контрагенты"); 
СпрОтделений = СоздатьОбъект("Справочник.ПрофилиОтделений");
СпрСпециальность = СоздатьОбъект("Справочник.ВрачебныеСпециальности");
НомерПоПорядку=1; 
ВыбратьСтроки(); 
Пока ПолучитьСтроку() = 1 Цикл
Результат="";
Фамилия=ВРЕГ(Строка(СокрЛП(ФамилияПациента)));
Имя=ВРЕГ(СокрЛП(ИмяПациента)); 
Отчество=ВРЕГ(ОтчествоПациента);
Пол=ВРЕГ(ПолПациента);
ДатаРожд = Дата(Формат((Дата(СокрЛП(ДатаРожденияПациента))),"ДДММГГ"));	
Диагноз=СокрЛП(КодОсновногоЗаболевания);
Статус=СтатусЗастрахованного;
Профиль=КодПрофиля;
Специальность=СокрЛП(КодСпециальности);
ОкончаниеСрокаПолиса= ДатаОкончанияПолиса;
ПериодБолезни = ДатаОкончанияЛечения - ДатаНачалаЛечения;
Если (ПериодБолезни=0) Тогда
ПериодБолезни=1;  
КонецЕсли;
Сумма = СуммаКОплате;
Возраст=Цел((ДатаНачалаЛечения-ДатаРожденияПациента)/365.25);
Если (Возраст<1) Тогда
Возраст=1;  
КонецЕсли;	 
ОГРН = СокрЛП(ОГРНЛПУ); 
СуммаПоТарифу = 0; 
Если (ОГРН<>"1030900711203") и (ОГРН<>"1030900709575") Тогда // стоматологические услуги не проверяем
Если (ВидМедицинскойПомощи = 1) или (ВидМедицинскойПомощи = 3) Тогда // Стационар
Если СпрЛПУ.НайтиПоРеквизиту("ОГРН", ОГРН,1)=1 Тогда // ЛПУ найдено и это не стоматология 
СпрСтационар.НайтиПоРеквизиту("ПрофильОтделения", Профиль,1); // находим нужную строку в справочнике
Если (ОГРН = "1030900721752") или (ОГРН = "1020900508001") или (ОГРН = "1030900708794") Тогда // республиканский уровень оказания мед.помощи
СуммаПоТарифуДети = СпрСтационар.РеспДети * ПериодБолезни;
СуммаПоТарифуВзрослые = СпрСтационар.РеспВзрослые * ПериодБолезни;
Если (Возраст <18) Тогда // пациент несовершеннолетний 
Сообщить("Сумма по тарифу - ", СуммаПоТарифу);
Если СуммаПоТарифуДети<>Сумма Тогда Результат = "V";
КонецЕсли;
ИначеЕсли СуммаПоТарифуВзрослые<>Сумма Тогда Результат = "V";
КонецЕсли; 
КонецЕсли;
Если ((ОГРН = "1030900715020") и (Профиль<>7)) или ((ОГРН = "1030900721807") и ((Профиль<>21) и (Профиль<>44))) Тогда // городской уровень оказания мед.помощи
СуммаПоТарифуДети = СпрСтационар.ГорДети * ПериодБолезни;
СуммаПоТарифуВзрослые = СпрСтационар.ГорВзрослые * ПериодБолезни;
Если (Возраст <18) Тогда // пациент несовершеннолетний 
Сообщить("Сумма по тарифу - ", СуммаПоТарифу);
Если СуммаПоТарифуДети <> Сумма Тогда Результат = "V";
КонецЕсли;
ИначеЕсли СуммаПоТарифуВзрослые <> Сумма Тогда Результат = "V";
КонецЕсли; 
КонецЕсли;
Если (ОГРН = "1040900707759") или (ОГРН = "1020900752509") или (ОГРН = "1020900729783") или (ОГРН = "1020900612875") или (ОГРН = "1020900974269") или (ОГРН = "1020900691393") или (ОГРН = "1020900975292") или (ОГРН = "1020900777996") Тогда // городской уровень оказания мед.помощи
СуммаПоТарифуДети = СпрСтационар.МуницДети * ПериодБолезни;
СуммаПоТарифуВзрослые = СпрСтационар.МуницВзрослые * ПериодБолезни;
Если (Возраст <18) Тогда // пациент несовершеннолетний			  
Если СуммаПоТарифуДети <> Сумма Тогда Результат = "V";
КонецЕсли;
ИначеЕсли СуммаПоТарифуВзрослые <> Сумма Тогда Результат = "V";
КонецЕсли; 
КонецЕсли;
КонецЕсли;
КонецЕсли;

Если (ВидМедицинскойПомощи = 2) Тогда // поликлиника
Сообщить("ОГРН - ", ОГРН);
Если СпрЛПУ.НайтиПоРеквизиту("ОГРН", ОГРН,1)=1 Тогда // ЛПУ найдено и это не стоматология 
Сообщить("Код Специальности - ", Специальность);
СпрСпециальность.НайтиПоКоду(Число(Специальность),0); 
Сообщить("Наименование Специальности - ", Специальность);					
СпрПоликлиника.НайтиПоРеквизиту("ВрачебнаяСпециальность", СпрСпециальность, 1); //Находим нужную строку в справочнике тарифов поликлиники
Если (ОГРН = "1030900707463") или (ОГРН = "1030900708805") или (ОГРН = "1030900721752") или (ОГРН = "1020900508001") или (ОГРН = "1030900708794") или (ОГРН = "1020900513941") или (ОГРН = "1020900511389") или (ОГРН = "1020900776709") или (ОГРН = "1030900715020") или (ОГРН = "1030900721807") Тогда // первый уровень оказания мед.помощи
СуммyаПоТарифуДети = СпрПоликлиника.ТекущийЭлемент().ПервыйДети * ПериодБолезни;
СуммаПоТарифуВзрослые = СпрПоликлиника.ТекущийЭлемент().ПервыйВзрослые * ПериодБолезни;
Если (Возраст <18) Тогда // пациент несовершеннолетний
Сообщить("Тариф первый взрослый - ", СпрПоликлиника.ПервыйВзрослые);
Сообщить("Период болезни - ", ПериодБолезни);
Сообщить("Сумма по тарифу - ", СуммаПоТарифу);
Если СуммаПоТарифуДети <> Сумма Тогда Результат = "V";
КонецЕсли;
ИначеЕсли СуммаПоТарифуВзрослые <> Сумма Тогда Результат = "V";
КонецЕсли; 
КонецЕсли;
Если (ОГРН = "1090917000041") или (ОГРН = "1040900707759") или (ОГРН = "1020900752509") или (ОГРН = "1020900729783") или (ОГРН = "1020900612875") или (ОГРН = "1020900974269") или (ОГРН = "1020900691393") или (ОГРН = "1020900975292") или (ОГРН = "1020900777996") Тогда // городской уровень оказания мед.помощи
СуммаПоТарифуДети = СпрПоликлиника.ТекущийЭлемент().ВторойДети * ПериодБолезни;
СуммаПоТарифуВзрослые = СпрПоликлиника.ТекущийЭлемент().ВторойВзрослые * ПериодБолезни;							
Если (Возраст <18) Тогда // пациент несовершеннолетний 
Если СуммаПоТарифуДети <> Сумма Тогда Результат = "V";
КонецЕсли;
ИначеЕсли (СуммаПоТарифуВзрослые <> Сумма) Тогда Результат = "V";
КонецЕсли; 
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли; 
Если Результат = "V" Тогда
ТЗ.НоваяСтрока();
ТЗ.Фамилия = Фамилия;
ТЗ.Имя = Имя;
ТЗ.Отчество = Отчество;
ТЗ.ДатаРождения = ДатаРожд;
ТЗ.Пол = Пол;
ТЗ.ПорядковыйНомер = НомерПоПорядку;
ТЗ.ПроверкаТарифа = Результат;			
КонецЕсли;
НомерПоПорядку=НомерПоПорядку+1;
КонецЦикла;		
Таб=СоздатьОбъект("Таблица");
Таб.ИсходнаяТаблица("ПроверкаТарифов");
Таб.ВывестиСекцию("Заголовок");
ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку()=1 Цикл
Фамилия=ТЗ.Фамилия; 
Имя=ТЗ.Имя;	  
Отчество=ТЗ.Отчество;
ДатаРождения = ТЗ.ДатаРождения;
Пол = ТЗ.Пол;
НомерПП = ТЗ.ПорядковыйНомер;
ПроверкаТарифа = ТЗ.ПроверкаТарифа;
Таб.ВывестиСекцию("Ошибка");
КонецЦикла; 
Таб.ТолькоПросмотр(1);
Таб.ПараметрыСтраницы(1,100,1);
Таб.Показать("ПроверкаТарифов",""); 
Сообщить("Контроль тарифов выполнен");
КонецПроцедуры
 
Вариант раз - у тех реквизитов,по которым ищем не установлен признак сортировка. При таком раскладе всегда будет возвращаться ноль или ругаться.

Вариант 2 СпрПоликлиника.НайтиПоРеквизиту("ВрачебнаяСпециальность", СпрСпециальность, 1); - зачем тут искать в пределах подчинения и где они заданы?

Вариант 3 - тарифы периодические и их надо вытаскивать методом получить(). Кстати может быть что дата значения тарифа просто пустая.
 
Вариант раз - у тех реквизитов,по которым ищем не установлен признак сортировка. При таком раскладе всегда будет возвращаться ноль или ругаться.

Вариант 2 СпрПоликлиника.НайтиПоРеквизиту("ВрачебнаяСпециальность", СпрСпециальность, 1); - зачем тут искать в пределах подчинения и где они заданы?

Вариант 3 - тарифы периодические и их надо вытаскивать методом получить(). Кстати может быть что дата значения тарифа просто пустая.
Была куча проблем с ЗП, только щас смог вернуться к решению данного вопроса.
Реквизиты непериодические, признак сортировки установлен. Насчет пределов подчинения не совсем понял, по-моему при 1 поиск просто идет по всему справочнику.
 
Попробуй подставлять
Код:
Сообщить()
 
А совпадают ли типы переменных "Профиль" и "КодПрофиля" ?
 
Попробуй подставлять
Код:
Сообщить()
Естественно пробовал, я и через отладчик все прогонял кучу раз - значения тарифных сумм он берет как нулевые, хотя в справочнике забиты совсем другие цифры!

А совпадают ли типы переменных "Профиль" и "КодПрофиля" ?
Совпадают) Видимо ошибка где-то в синтаксисе и 1С просто не получает доступ к нужным значениям. Вот только где она - ума не приложу :sorry:
 
Ну, кидай базу, если возможно, разберемся
 
СпрПоликлиника.НайтиПоРеквизиту("ВрачебнаяСпециальность", СпрСпециальность, 1); //Находим нужную строку в справочнике тарифов поликлиники

По-моему должно быть

СпрПоликлиника.НайтиПоРеквизиту("ВрачебнаяСпециальность", СпрСпециальность.ТекущийЭлемент(), 1); //Находим нужную строку в справочнике тарифов поликлиники

или
СпрПоликлиника.НайтиПоРеквизиту("ВрачебнаяСпециальность", СпрСпециальность.ТекущийЭлемент().Код, 1); //Находим нужную строку в справочнике тарифов поликлиники

в зависимости от того какого типа "ВрачебнаяСпециальность"
 
Глория, вы были абсолютно правы! Нужно было написать
СпрПоликлиника.НайтиПоРеквизиту("ВрачебнаяСпециальность", СпрСпециальность.ТекущийЭлемент(), 1.
Что касается стационара - то там вообще строка пропала:
СпрОтделений.НайтиПоКоду(Профиль)

Всем огромное спасибо :D