Имя: Пароль:
1C
1C 7.7
v7: Помогите разобраться с ФС.НайтиСледующийФайл()
0 kkursor
 
27.11.11
17:45
Добрый день, господа!
Есть вопрос. В нашей конфигурации в модуле пробивания чеков по кассе есть фрагмент кода, который скидывает чек в MXL-ную табличку. По данным сотни этих табличек в конце месяца запускается отчёт, по которому определяется, какой кассир сколько напродавал и сколько бонусов ему дать. Файл скидывается в рабочий каталог кассира с именем в формате ДатаВремяIDКассы.mxl, типа 27111110391717045.mxl.
Так вот. Я сегодня обнаружил, что в отчёт за сегодня попал чек от кассира, который уже полгода не работает. Стал разбираться. Оказалось, что чек пробит 27 мая (соответственно имя файла начинается с 270511...). Фрагмент кода, обрабатывающего эти чеки, выглядит так:

ИмяФайлаПоиска=СтрЗаменить(Строка(ТекДата),".","");
ФС.УстТекКаталог(СокрЛП(Путь));
ИмяФайлаНайденного=ФС.НайтиПервыйФайл(ИмяФайлаПоиска+"*.mxl");
                               
ВсегоЧеков=0;
   Пока ИмяФайлаНайденного<>"" Цикл        
           ...
       КонецЦикла;
ИмяФайлаНайденного=ФС.НайтиСледующийФайл();

Я добавил в цикл проверку:
Если Лев(ИмяФайлаНайденного, 6) <> СтрЗаменить(Строка(ТекДата),".","") Тогда продолжить; КонецЕсли;

Проверка отсеивает неправильные файлы, но, поскольку они попадают в выборку, база наглухо виснет, ибо их там очень много.

Собственно вопрос - из-за чего так получается и как это исправить? По-моему 270511блабла.mxl под формат 271111*.mxl подходит чуть лучше, чем никак :(

P.S. Я новичок в одном эсе, не ругайтесь на меня, если что. :)
1 zak555
 
27.11.11
17:46
это ТИС ?
2 kkursor
 
27.11.11
17:51
Это самопальная до ужаса конфигурация, осталась в наследство от прошлого 1С-ника
3 Rie
 
27.11.11
17:56
(0) Я бы тоже завис, если бы мне сказали переходить к следующему файлу только _после_ того, как завершится _бесконечный_ цикл (ведь ИмяФайлаНайденного _внутри_ цикла НЕ изменяется).
4 kkursor
 
27.11.11
18:40
Я при копировании куска не тот конец цикла убрал. С этим в обработке всё ок. Вопрос - почему под маску 271111*.mxl попадает 270511блабла.mxl?
5 Злопчинский
 
27.11.11
19:01
потому что м.б. кто-то пошаманил с датой на компьютере...
6 kkursor
 
27.11.11
19:23
В каком смысле? Дата 27.11.11 введена юзером, это не текущая дата. В процессе выполнения обработки она не меняется. Файлик 270511.......mxl создан в мае...
7 Rie
 
27.11.11
19:28
(6) Что такое ТекДата?
Какое значение имеет ИмяФайлаПоиска?
8 kkursor
 
27.11.11
19:54
Короче вот полный текст обработки.

Перем Путь1;
Перем Путь2;
Перем Путь3;
Перем Путь4;
Перем Путь5;

Функция ПеребратьЧеки(Путь, ТекДата, ТЗ)      
   Таб=СоздатьОбъект("Таблица");
   
   ИмяФайлаПоиска=СтрЗаменить(Строка(ТекДата),".","");
   ФС.УстТекКаталог(СокрЛП(Путь));
   ИмяФайлаНайденного=ФС.НайтиПервыйФайл(ИмяФайлаПоиска+"???.mxl");
                               
   ВсегоЧеков=0;
   Пока ИмяФайлаНайденного<>"" Цикл        
       Если Лев(ИмяФайлаНайденного, 6) <> СтрЗаменить(Строка(ТекДата),".","") Тогда продолжить; КонецЕсли;
       ВсегоЧеков=ВсегоЧеков+1;
       Таб.Открыть(СокрЛП(Путь)+ИмяФайлаНайденного);
       Если Таб.Область(Таб.ВысотаТаблицы(),2).Текст="Продажа" Тогда
           Коэф=1;
       Иначе
           Коэф=-1;
       КонецЕсли;            
       
       Товар=СоздатьОбъект("Справочник.Товар");  
       
       Для к=1 по (Таб.ВысотаТаблицы()) Цикл      
           Если Число(Таб.Область(к,4).Текст)>0 Тогда  
               Товар.НайтиПоКоду(Таб.Область(к,5).Текст);
               ТЗ.НоваяСтрока();
               ТЗ.Позиция=Товар.Наименование;
               ТЗ.Количество=Число(Таб.Область(к,4).Текст)*Коэф;
               ТЗ.Цена=Число(Таб.Область(к,3).Текст);
               ТЗ.Сумма=ТЗ.Цена*ТЗ.Количество;  
               ТЗ.Продавец=Таб.Область(Таб.ВысотаТаблицы(),4).Текст;
               Если ТЗ.Продавец="Епур Галина Сергеевна" тогда сообщить(СокрЛП(Путь)+ИмяФайлаНайденного); конецесли;
               ТЗ.Код=Таб.Область(к,5);
               ТЗ.Наименование=Таб.Область(к,1).Текст;
               ТЗ.Дата=ТекДата;    
               ТЗ.Позиций=1;  
               Если к=1 Тогда ТЗ.Скидка=Число(Таб.Область(Таб.ВысотаТаблицы(),5).Текст)*Коэф; ТЗ.Чеков=1; КонецЕсли; // Учитываем скидку и количество чеков только один раз.
               Иначе Продолжить;
           КонецЕсли;                              
       КонецЦикла;                        
       ИмяФайлаНайденного=ФС.НайтиСледующийФайл();    
       
   КонецЦикла;                        
   Сообщить("Произведён поиск в "+ВсегоЧеков+" чеках за "+ТекДата+"");        
   Возврат ТЗ;
КонецФункции

//*******************************************
Процедура Сформировать()
   Если Число(НачДата)=0 Тогда
       Предупреждение ("Укажите начальную дату!");
       Возврат;                      
   КонецЕсли;                                      
   
   Если Число(НачДата)>Число(КонДата) Тогда
       Предупреждение ("Указанная начальная дата более поздняя, чем указанная конечная дата.");
       Возврат;
   КонецЕсли;
       
   ТЗ=СоздатьОбъект("ТаблицаЗначений");
   ТЗ.НоваяКолонка("Позиция","Справочник.Товар");
   ТЗ.НоваяКолонка("Цена","Число",10,2);
   ТЗ.НоваяКолонка("Количество","Число",10);
   ТЗ.НоваяКолонка("Сумма","Число",10,2);    
   ТЗ.НоваяКолонка("Продавец", "Текст", 50);  
   ТЗ.НоваяКолонка("Код", "Текст", 15);
   ТЗ.НоваяКолонка("Наименование", "Текст", 50);      
   ТЗ.НоваяКолонка("Дата", "Дата");            
   ТЗ.НоваяКолонка("Чеков", "Число");   // эти две
   ТЗ.НоваяКолонка("Позиций", "Число"); // колонки ниже суммируются с помощью метода Свернуть()    
   ТЗ.НоваяКолонка("Скидка", "Число", 10, 2);
       
   ТекДата = НачДата;                        
   
   Пока (КонДата+1)<>ТекДата Цикл
       Если ПустаяСтрока(Путь1)=0 Тогда ТЗ=ПеребратьЧеки(Путь1, ТекДата, ТЗ);  КонецЕсли;
       Если ПустаяСтрока(Путь2)=0 Тогда ТЗ=ПеребратьЧеки(Путь2, ТекДата, ТЗ);  КонецЕсли;
       Если ПустаяСтрока(Путь3)=0 Тогда ТЗ=ПеребратьЧеки(Путь3, ТекДата, ТЗ);  КонецЕсли;    
       Если ПустаяСтрока(Путь4)=0 Тогда ТЗ=ПеребратьЧеки(Путь4, ТекДата, ТЗ);  КонецЕсли;    
       Если ПустаяСтрока(Путь5)=0 Тогда ТЗ=ПеребратьЧеки(Путь5, ТекДата, ТЗ);  КонецЕсли;    
       ТекДата=ТекДата+1;
   КонецЦикла;                                                                                                                                                    
                                                                                               
   ТЗ.Свернуть("Дата,Продавец", "Количество,Сумма,Чеков,Позиций,Скидка"); // сложить повторяшки                                                                    
   ТЗ.Сортировать("+Дата,+Продавец");    // сортируем ТЗ сначала по дате, а потом по ФИО продавца
   
   Если ТЗ.КоличествоСтрок()>0 Тогда
       Отчёт=СоздатьОбъект("Таблица");
       Отчёт.ИсходнаяТаблица("Таблица");
       Отчёт.ВывестиСекцию("Шапка");            
         
       ТекДата=ТЗ.ПолучитьЗначение(1, "Дата");
       Отчёт.ВывестиСекцию("День");      
       
       ТЗ.ВыбратьСтроки();
       Пока ТЗ.ПолучитьСтроку()=1 цикл        
             Если ТекДата<>ТЗ.ПолучитьЗначение(ТЗ.НомерСтроки, "Дата") Тогда        
                     ТекДата=ТЗ.ПолучитьЗначение(ТЗ.НомерСтроки, "Дата");      
                   Отчёт.ВывестиСекцию("День");        
             КонецЕсли;                
             Отчёт.ВывестиСекцию("Строка");      
       КонецЦикла;              
   КонецЕсли;                          
   
   // Подведение итогов за период
   Отчёт.ВывестиСекцию("Итого");        
   ТЗ.Свернуть("Продавец", "Количество,Сумма,Чеков,Позиций,Скидка"); // подведение итогов за период, сворачивание по имени продавца
   ТЗ.Сортировать("+Продавец");
   ТЗ.ВыбратьСтроки();
   Пока ТЗ.ПолучитьСтроку()=1 цикл        
       Отчёт.ВывестиСекцию("Строка");      
   КонецЦикла;            
                                       
   Отчёт.Показать();
КонецПроцедуры
               
// Все пути должны быть с закрывающим \ !!!
Путь1="\\s\o\Кассир1\";
Путь2="\\s\o\Кассир2\";
Путь3="\\s\o\Кассир4\";
Путь4="\\p\o\Кассир3\";
Путь5="\\s\o\КассирМ1\";
Заголовок="Имя фирмы";

ТекДата - текущая дата, перебираемая циклом в интервале (НачДата, КонДата). Это собственно два аргумента, которые принимает обработка.
ИмяФайлаПоиска правильное значение имеет, 271111.
Я тут разобрался, почему он на следующий файл не переключается. Добавил в условие

Если Лев(ИмяФайлаНайденного, 6) <> СтрЗаменить(Строка(ТекДата),".","") Тогда продолжить; КонецЕсли;

изменение ФС:
Если Лев(ИмяФайлаНайденного, 6) <> СтрЗаменить(Строка(ТекДата),".","") Тогда продолжить; ИмяФайлаНайденного=ФС.НайтиСледующийФайл();    КонецЕсли;

Но всё равно очень интересно узнать, почему неправильный файл из ФС получается.
9 kkursor
 
27.11.11
19:56
ИмяФайлаНайденного=ФС.НайтиПервыйФайл(ИмяФайлаПоиска+"???.mxl");

стоит читать как

ИмяФайлаНайденного=ФС.НайтиПервыйФайл(ИмяФайлаПоиска+"*.mxl");

это я пытался нагугленные решения попробовать
10 kkursor
 
27.11.11
20:08
Если Лев(ИмяФайлаНайденного, 6) <> СтрЗаменить(Строка(ТекДата),".","") Тогда ИмяФайлаНайденного=ФС.НайтиСледующийФайл(); продолжить;    КонецЕсли;

Почему тут посты править нельзя :(
11 kkursor
 
27.11.11
20:12
В общем я придумал workaround в виде дополнительной проверки на вшивость, просто очень хочется узнать, почему оно именно так срабатывает :( Есть у кого идеи?
12 Rie
 
27.11.11
20:20
(11) Идея проста - чудес не бывает. Что-то не так с маской, несмотря на вышеизложенное.
Или не весь код приведен, и где-то сбивается выборка файлов (обращением к ФС).
Или с путями что-то неладно, и файл появляется не при первом обращении к.

Если явно присвоить ИмяФайлаПоиска = "271111" - что получится?
13 kkursor
 
27.11.11
21:06
>Или не весь код приведен, и где-то сбивается выборка файлов (обращением к ФС).
Весь код. Полностью.

>Или с путями что-то неладно, и файл появляется не при первом обращении к.
Да, не при первом. Это появляется не при первом обращении. Нужно n раз запустить ФС.СледующийФайл()

>Если явно присвоить ИмяФайлаПоиска = "271111" - что получится?
То же самое - 270511 попадает в выборку.
14 Злопчинский
 
27.11.11
21:30
> Если явно присвоить ИмяФайлаПоиска = "271111" - что получится?
То же самое - 270511 попадает в выборку.
- НЕ ВЕРЮ!
15 Rie
 
27.11.11
21:33
(13) Может, у Вас где-то написано не ИмяФайлаПоиска, а что-нибудь вроде ИмяФaйлаПоиска, или же ИмяФайлаПoискa? (я имею в виду, что внешний вид букв бывает обманчив).
16 Злопчинский
 
27.11.11
21:36
ТекДата - пустое значение, соответственно идет выборка по маске *.mxl - выбираются все файлы.
17 Злопчинский
 
27.11.11
21:37
Достаточно
.
Функция ПеребратьЧеки(Путь, ТекДата, ТЗ)      
.
заменить на
.
Функция ПеребратьЧеки(Путь, ТекДата, ТЗ)      
Сообщить("текДата="+ТекДата);
.
и посмотреть что будет
18 Rie
 
27.11.11
21:38
(16) Он это проверяет. Криво - но проверяет.
19 Злопчинский
 
27.11.11
21:40
а автору в помощь: http://infostart.ru/public/14794/
но это - потом! сначала забороть текущую проблему...
20 Злопчинский
 
27.11.11
21:41
автор пусть не пыхтит, а достаточно в отладчике хотя бы поставить точку останова с условием и посмотреть..
работы блин на 10 минут вна всю проблему...
21 andrewks
 
27.11.11
21:44
(19) это чо за жесткач? http://savepic.su/827097.htm
22 Злопчинский
 
27.11.11
21:47
(21) что и написано - большими жирными красными буквами - а то задолбали вопросы задавать - я открываю обработку а она ничего не показывает... ;-)
.
на Исе очереднйо редизайн - криво показывает
23 Злопчинский
 
27.11.11
21:49
ПеребратьЧеки() - вообще грязно очень написана
вместо того, чтобы один раз пройтись по списку файлов - отсеивая ненужные и обрабатывая каждый нужный файл - для каждой даты пробегается весь список файлов.. т.е. вместо 1 перебора файлов имеем N переборов.. но это ладно..
24 kkursor
 
27.11.11
22:02
>>> Если явно присвоить ИмяФайлаПоиска = "271111" - что получится?
>>То же самое - 270511 попадает в выборку.
>- НЕ ВЕРЮ!
Точно-точно :(

>(13) Может, у Вас где-то написано не ИмяФайлаПоиска, а что-нибудь вроде ИмяФaйлаПоиска, или же ИмяФайлаПoискa? (я имею в виду, что внешний вид букв бывает обманчив).
Да нет, писал я... Если бы было ИмяФaйлаПоиска или ИмяФайлаПoискa - ругалось бы на неопределённую переменную.

>ТекДата - пустое значение, соответственно идет выборка по маске *.mxl - выбираются все файлы.
Не-а, не пустое. И правильное.
27.11.11
Произведён поиск в 64 чеках за 27.11.11
27.11.11
Произведён поиск в 90 чеках за 27.11.11
27.11.11
Произведён поиск в 0 чеках за 27.11.11
27.11.11
Произведён поиск в 0 чеках за 27.11.11
27.11.11
Произведён поиск в 0 чеках за 27.11.11

>Криво - но проверяет.
Почему криво? Объясните, я исправлюсь :)

>автор пусть не пыхтит, а достаточно в отладчике хотя бы поставить точку останова с условием и посмотреть..
Смотрел. Просто начиная с определённого момента он берёт файл не 271111..., а 270511. Остальные параметры в порядке.

>ПеребратьЧеки() - вообще грязно очень написана. вместо того, чтобы один раз пройтись по списку файлов - отсеивая ненужные и обрабатывая каждый нужный файл - для каждой даты пробегается весь список файлов.. т.е. вместо 1 перебора файлов имеем N переборов.. но это ладно..
А какая разница? Что я для каждой даты пробегаю список файлов, что сразу согнать все файлы в ТЗ, а потом открывать, получая оттуда...
25 Злопчинский
 
27.11.11
22:09
> А какая разница?
ты для каждой даты из интервала пробегаешь весь список файлов.
имея 30 дат и список файлов в 100 шту - ты перебираешь 3000 файлов.
вместо того, чтобы перебрать 100 файлов.
26 Злопчинский
 
27.11.11
22:12
не верю!!
.
дай сюда текущий код функции ПеребратьЧеки() - без своих излишних домыслов и исправлений.
приведи его в том виде, в котором он выполняется сейчас.
27 Rie
 
27.11.11
22:14
(24) Прямо - это ПустоеЗначение(НачДата)=1
Да и завершение цикла по датам:
Пока ТекДата<КонДата Цикл

Но главный вопрос - с какого такого "определённого момента"? Какие значения имеют переменные в этот "определённый момент"?

И ещё один главный вопрос - а почему твоя процедура не зацикливается? Ведь твой work-around не может её не зациклить. Значит, работает не тот код, что в (8). А какой?
28 kkursor
 
27.11.11
22:20
Текущий код функции:

Функция ПеребратьЧеки(Путь, ТекДата, ТЗ)      
   Сообщить(ТекДата);
   Таб=СоздатьОбъект("Таблица");
   
   ИмяФайлаПоиска="271111";//СтрЗаменить(Строка(ТекДата),".","");
   //ИмяФайлаПоиска=Сред(ИмяФайлаПоиска,1,4)+Прав(Строка(ДатаГод(ТекДата)),2);  
   ФС.УстТекКаталог(СокрЛП(Путь));
   ИмяФайлаНайденного=ФС.НайтиПервыйФайл(ИмяФайлаПоиска+"*.mxl");
                               
   ВсегоЧеков=0;
   Пока ИмяФайлаНайденного<>"" Цикл        
       //Если Лев(ИмяФайлаНайденного, 6) <> СтрЗаменить(Строка(ТекДата),".","") Тогда ИмяФайлаНайденного=ФС.НайтиСледующийФайл(); продолжить; КонецЕсли; - закомментированный Work-Around. Работает!
       ВсегоЧеков=ВсегоЧеков+1;
       Таб.Открыть(СокрЛП(Путь)+ИмяФайлаНайденного);
       Если Таб.Область(Таб.ВысотаТаблицы(),2).Текст="Продажа" Тогда
           Коэф=1;
       Иначе
           Коэф=-1;
       КонецЕсли;            
       
       Товар=СоздатьОбъект("Справочник.Товар");  
       
       Для к=1 по (Таб.ВысотаТаблицы()) Цикл      
           Если Число(Таб.Область(к,4).Текст)>0 Тогда  
               Товар.НайтиПоКоду(Таб.Область(к,5).Текст);
               ТЗ.НоваяСтрока();
               ТЗ.Позиция=Товар.Наименование;
               ТЗ.Количество=Число(Таб.Область(к,4).Текст)*Коэф;
               ТЗ.Цена=Число(Таб.Область(к,3).Текст);
               ТЗ.Сумма=ТЗ.Цена*ТЗ.Количество;  
               ТЗ.Продавец=Таб.Область(Таб.ВысотаТаблицы(),4).Текст;
//                Если ТЗ.Продавец="Епур Галина Сергеевна" тогда сообщить(СокрЛП(Путь)+ИмяФайлаНайденного); конецесли;
               ТЗ.Код=Таб.Область(к,5);
               ТЗ.Наименование=Таб.Область(к,1).Текст;
               ТЗ.Дата=ТекДата;    
               ТЗ.Позиций=1;  
               Если к=1 Тогда ТЗ.Скидка=Число(Таб.Область(Таб.ВысотаТаблицы(),5).Текст)*Коэф; ТЗ.Чеков=1; КонецЕсли; // Учитываем скидку и количество чеков только один раз.
               Иначе Продолжить;
           КонецЕсли;                              
       КонецЦикла;                        
       ИмяФайлаНайденного=ФС.НайтиСледующийФайл();    
       
   КонецЦикла;                        
   Сообщить("Произведён поиск в "+ВсегоЧеков+" чеках за "+ТекДата+"");        
   Возврат ТЗ;
КонецФункции

>ты для каждой даты из интервала пробегаешь весь список файлов.
имея 30 дат и список файлов в 100 шту - ты перебираешь 3000 файлов.
вместо того, чтобы перебрать 100 файлов.
А разве маска не даёт выборку как раз с той целью, чтобы все стопитсот файлов не перелопачивать?

>Но главный вопрос - с какого такого "определённого момента"? Какие значения имеют переменные в этот "определённый момент"?
ИмяФайлаНайденного = "270511144445822400182176.mxl"
Лев(ИмяФайлаНайденного, 6) = "270511"
СтрЗаменить(Строка(ТекДата),".","") = "271111"
всегочеков = 89
ИмяФайлаПоиска = "271111"
29 Злопчинский
 
27.11.11
22:25
по коду не видно где определяеться значение переменной
ИмяФайлаПоиска
30 kkursor
 
27.11.11
22:28
(29), 5ая строка
31 Злопчинский
 
27.11.11
22:36
сделай новую обормотку дубль текущей
вставь туда по быстому переваял
.
Перем Путь1;
Перем Путь2;
Перем Путь3;
Перем Путь4;
Перем Путь5;

Функция ПеребратьЧеки(Путь, ДатаНачала, ДатаКонца, ТЗ)      

   Таб=СоздатьОбъект("Таблица");
   
   ФС.УстТекКаталог(СокрЛП(Путь));
   ИмяФайлаНайденного = ФС.НайтиПервыйФайл(+"*.mxl");
                               
   Пока ИмяФайлаПоиска<>""
   Цикл
       
       ДатаТекущегоФайлаДД = Число(Лев(ИмяФайлаПоиска,2));
       ДатаТекущегоФайлаММ = Число(Сред(ИмяФайлаПоиска,3,2));
       ДатаТекущегоФайлаГГ = 2000+Число(Сред(ИмяФайлаПоиска,5,2));
       ДатаТекущегоФайла    = Дата(ДатаТекущегоФайлаГГ,ДатаТекущегоФайлаММ,ДатаТекущегоФайлаДД);
       
       Если ДатаТекущегоФайла < ДатаНачала
       Тогда
           ИмяФайлаНайденного=ФС.НайтиСледующийФайл();
           Продолжить;
       КонецЕсли;
       
       Если ДатаТекущегоФайла > ДатаКонца
       Тогда
           ИмяФайлаНайденного=ФС.НайтиСледующийФайл();
           Продолжить;
       КонецЕсли;
       
       Таб.Открыть(СокрЛП(Путь)+ИмяФайлаНайденного);
       Если Таб.Область(Таб.ВысотаТаблицы(),2).Текст="Продажа" Тогда
           Коэф=1;
       Иначе
           Коэф=-1;
       КонецЕсли;            
       
       Товар=СоздатьОбъект("Справочник.Товар");  
       
       Для к=1 по (Таб.ВысотаТаблицы())
       Цикл      
           
           Если Число(Таб.Область(к,4).Текст)<=0
           Тогда  
               Продолжить;
           КонецЕсли;
           
           Товар.НайтиПоКоду(Таб.Область(к,5).Текст);
           ТЗ.НоваяСтрока();
           ТЗ.Позиция        =Товар.Наименование;
           ТЗ.Количество    =Число(Таб.Область(к,4).Текст)*Коэф;
           ТЗ.Цена            =Число(Таб.Область(к,3).Текст);
           ТЗ.Сумма        =ТЗ.Цена*ТЗ.Количество;  
           ТЗ.Продавец        =Таб.Область(Таб.ВысотаТаблицы(),4).Текст;
           Если ТЗ.Продавец="Епур Галина Сергеевна"
           Тогда
               Сообщить(СокрЛП(Путь)+ИмяФайлаНайденного);
           КонецЕсли;
           
           ТЗ.Код            =Таб.Область(к,5);
           ТЗ.Наименование    =Таб.Область(к,1).Текст;
           ТЗ.Дата            =ТекДата;    
           ТЗ.Позиций        =1;  
           Если к=1
           Тогда
               ТЗ.Скидка=Число(Таб.Область(Таб.ВысотаТаблицы(),5).Текст)*Коэф;
               ТЗ.Чеков=1;
           КонецЕсли; // Учитываем скидку и количество чеков только один раз.

       КонецЦикла;                        
       ИмяФайлаНайденного = ФС.НайтиСледующийФайл();    
       
   КонецЦикла;                        
   
   //Сообщить("Произведён поиск в "+ВсегоЧеков+" чеках за "+ТекДата+"");        
   Возврат ТЗ;
КонецФункции

//*******************************************

Процедура Сформировать()
   Если Число(НачДата)=0 Тогда
       Предупреждение ("Укажите начальную дату!");
       Возврат;                      
   КонецЕсли;                                      
   
   Если Число(НачДата)>Число(КонДата) Тогда
       Предупреждение ("Указанная начальная дата более поздняя, чем указанная конечная дата.");
       Возврат;
   КонецЕсли;
       
   ТЗ=СоздатьОбъект("ТаблицаЗначений");
   ТЗ.НоваяКолонка("Позиция","Справочник.Товар");
   ТЗ.НоваяКолонка("Цена","Число",10,2);
   ТЗ.НоваяКолонка("Количество","Число",10);
   ТЗ.НоваяКолонка("Сумма","Число",10,2);    
   ТЗ.НоваяКолонка("Продавец", "Текст", 50);  
   ТЗ.НоваяКолонка("Код", "Текст", 15);
   ТЗ.НоваяКолонка("Наименование", "Текст", 50);      
   ТЗ.НоваяКолонка("Дата", "Дата");            
   ТЗ.НоваяКолонка("Чеков", "Число");   // эти две

   ТЗ.НоваяКолонка("Позиций", "Число"); // колонки ниже суммируются с помощью метода Свернуть()    
   ТЗ.НоваяКолонка("Скидка", "Число", 10, 2);
       
   Если ПустаяСтрока(Путь1)=0 Тогда ТЗ=ПеребратьЧеки(Путь1, НачДата, КонДата, ТЗ);  КонецЕсли;
   Если ПустаяСтрока(Путь2)=0 Тогда ТЗ=ПеребратьЧеки(Путь2, НачДата, КонДата, ТЗ);  КонецЕсли;
   Если ПустаяСтрока(Путь3)=0 Тогда ТЗ=ПеребратьЧеки(Путь3, НачДата, КонДата, ТЗ);  КонецЕсли;    
   Если ПустаяСтрока(Путь4)=0 Тогда ТЗ=ПеребратьЧеки(Путь4, НачДата, КонДата, ТЗ);  КонецЕсли;    
   Если ПустаяСтрока(Путь5)=0 Тогда ТЗ=ПеребратьЧеки(Путь5, НачДата, КонДата, ТЗ);  КонецЕсли;    
                                                                                               
   ТЗ.Свернуть("Дата,Продавец", "Количество,Сумма,Чеков,Позиций,Скидка"); // сложить повторяшки                                                                      
   ТЗ.Сортировать("+Дата,+Продавец");    // сортируем ТЗ сначала по дате, а потом по ФИО продавца
   
   Если ТЗ.КоличествоСтрок()>0
   Тогда
       Отчёт=СоздатьОбъект("Таблица");
       Отчёт.ИсходнаяТаблица("Таблица");
       Отчёт.ВывестиСекцию("Шапка");            
         
       ТекДата=ТЗ.ПолучитьЗначение(1, "Дата");
       Отчёт.ВывестиСекцию("День");      
       
       ТЗ.ВыбратьСтроки();
       Пока ТЗ.ПолучитьСтроку()=1
       Цикл        
           
           Если ТекДата<>ТЗ.ПолучитьЗначение(ТЗ.НомерСтроки, "Дата")
           Тогда        
                  ТекДата=ТЗ.ПолучитьЗначение(ТЗ.НомерСтроки, "Дата");      
                  Отчёт.ВывестиСекцию("День");        
           КонецЕсли;
               
           Отчёт.ВывестиСекцию("Строка");      
       КонецЦикла;              
   КонецЕсли;                          
   
   // Подведение итогов за период

   Отчёт.ВывестиСекцию("Итого");        
   ТЗ.Свернуть("Продавец", "Количество,Сумма,Чеков,Позиций,Скидка"); // подведение итогов за период, сворачивание по имени продавца

   ТЗ.Сортировать("+Продавец");
   ТЗ.ВыбратьСтроки();
   Пока ТЗ.ПолучитьСтроку()=1 цикл        
       Отчёт.ВывестиСекцию("Строка");      
   КонецЦикла;            
                                       
   Отчёт.Показать();
КонецПроцедуры
               
// Все пути должны быть с закрывающим \ !!!

Путь1="\\s\o\Кассир1\";
Путь2="\\s\o\Кассир2\";
Путь3="\\s\o\Кассир4\";
Путь4="\\p\o\Кассир3\";
Путь5="\\s\o\КассирМ1\";
Заголовок="Имя фирмы";
32 Злопчинский
 
27.11.11
22:38
Можешь еще для логгирования вставить:
перед
Таб.Открыть(СокрЛП(Путь)+ИмяФайлаНайденного);
вставить строку
Сообщить("Обрабатываем "+СокрЛП(Путь)+ИмяФайлаНайденного);
33 Злопчинский
 
27.11.11
22:39
почему-то думаю, что никаких ненужных файлов не вылезет... ;-)
34 Злопчинский
 
27.11.11
22:40
если чего - кидай на мыло [email protected]
bl и пароль на тимвьювер - залезу посмотрим совместно на тови чудеса..
35 hhhh
 
27.11.11
23:44
(30) а вот это что за бредовая строка у тебя?

  ТекДата = НачДата;
36 Torquader
 
28.11.11
01:09
Граждане земляне!
А слабо при закрытии смены на кассе все её чеки за эту смену собрать в один файл, где в заголовке записать общие итоги по файлу (по кассирам, видам оплаты и т.п.), чтобы не было необходимости перебирать кучу файлов.
Кроме того, формат ДатаВремяИдКассы - если это без разделителей, то это очень коряво, и придётся писать в шаблоне вопросы вместо времени, чтобы правильно выбирать файлы (и, надеюсь, что длина ИД известна заранее).
Удачи.
37 Злопчинский
 
28.11.11
02:28
(36) я думаю, что это не принципиально, такая инфа вряд ли используется для управления/оптимизации/расчетов.. имеет скорее оценивающий характер...
.
в свое время у меня была аналогичная фишка:
при печати реализации печатался также и протокол согласования цены - печатался такой какой ДОЛЖЕН БЫТЬ (паралельно сваливался в хранилище-папку на диске). в конце месяца проводился супермегапуперрегламент, по результатам которого "печатались" реальные протколы и сравнивались с заранее отложенными в хранилище...
38 Злопчинский
 
28.11.11
02:29
(36) ну а то, что не хватило тямы складировать имена начинающиеся хотя бы с UUUUVVLL для нормальной сортировки-группировки - это да, бяка...
39 TeddySlaf
 
28.11.11
03:04
(0) давайте выдвину совсем дикую версию.
А что, если ФС ищет не только в длинных именах файла, но и в коротких (в формате 8.3)?
А там как назло есть случайное совпадение первых 6-ти символов?
40 Злопчинский
 
28.11.11
19:00
(39) это ты мощно выступил!
насколько мне память не изменяет файло с именем 271111траляляля - штатно ну никак не может быть с коротким менем 251111~
41 kkursor
 
30.11.11
16:45
(31), сорри, тока дорвался. В вашем коде стопитсот синтаксических ошибок :( исправлять?

(35), >а вот это что за бредовая строка у тебя?
Счётчик цикла. Изначально устанавливается на начальную дату введённого диапазона и с каждой итерацией увеличивается на 1.

(36),
>А слабо при закрытии смены на кассе все её чеки за эту смену собрать в один файл, где в заголовке записать общие итоги по файлу (по кассирам, видам оплаты и т.п.), чтобы не было необходимости перебирать кучу файлов.
Об этом я не думал. Но эти чеки бывают нужны для отчётов - чтобы видеть, что во сколько продавалось, потом, по отчётам. Из базы эти чеки потом удаляются.

>Кроме того, формат ДатаВремяИдКассы - если это без разделителей, то это очень коряво, и придётся писать в шаблоне вопросы вместо времени, чтобы правильно выбирать файлы (и, надеюсь, что длина ИД известна заранее).
Да, длина ИД постоянная. Но от прошлого погромиста досталось куча отчётов, в которых именно со *-дочкой было. Я админ-линуксоед вапще, тока-тока постигаю эти ваши одинэсные штучки-дрючки :) жизнь заставляет вертеться

>(36) ну а то, что не хватило тямы складировать имена начинающиеся хотя бы с UUUUVVLL для нормальной сортировки-группировки - это да, бяка...
Что такое UUUUVVLL?

(39),
>давайте выдвину совсем дикую версию.
А что, если ФС ищет не только в длинных именах файла, но и в коротких (в формате 8.3)?
А там как назло есть случайное совпадение первых 6-ти символов?
Я думал об этом. Но не в первых символах ошибка. Он перелопачивает по выборке файлы 271111~1.MXL, а туда почему-то попадает 270511~1.MXL
42 filh
 
30.11.11
17:14
как ищешь, так и попадают
43 Злопчинский
 
30.11.11
17:51
(41) по (31) - ясен день исправляй...
.
специально для вас - без синтаксических ошибок
.
Перем Путь1;
Перем Путь2;
Перем Путь3;
Перем Путь4;
Перем Путь5;

Функция ПеребратьЧеки(Путь, ДатаНачала, ДатаКонца, ТЗ)      

   Таб=СоздатьОбъект("Таблица");
   
   ФС.УстТекКаталог(СокрЛП(Путь));
   ИмяФайлаНайденного = ФС.НайтиПервыйФайл(+"*.mxl");
                               
   Пока ИмяФайлаНайденного<>""
   Цикл
       
       ДатаТекущегоФайлаДД = Число(Лев(ИмяФайлаНайденного,2));
       ДатаТекущегоФайлаММ = Число(Сред(ИмяФайлаНайденного,3,2));
       ДатаТекущегоФайлаГГ = 2000+Число(Сред(ИмяФайлаНайденного,5,2));
       ДатаТекущегоФайла     = Дата(ДатаТекущегоФайлаГГ,ДатаТекущегоФайлаММ,ДатаТекущегоФайлаДД);
       
       Если ДатаТекущегоФайла < ДатаНачала
       Тогда
           ИмяФайлаНайденного=ФС.НайтиСледующийФайл();
           Продолжить;
       КонецЕсли;
       
       Если ДатаТекущегоФайла > ДатаКонца
       Тогда
           ИмяФайлаНайденного=ФС.НайтиСледующийФайл();
           Продолжить;
       КонецЕсли;
       
       Таб.Открыть(СокрЛП(Путь)+ИмяФайлаНайденного);
       Если Таб.Область(Таб.ВысотаТаблицы(),2).Текст="Продажа" Тогда
           Коэф=1;
       Иначе
           Коэф=-1;
       КонецЕсли;            
       
       Товар=СоздатьОбъект("Справочник.Товар");  
       
       Для к=1 по (Таб.ВысотаТаблицы())
       Цикл      
           
           Если Число(Таб.Область(к,4).Текст)<=0
           Тогда  
               Продолжить;
           КонецЕсли;
           
           Товар.НайтиПоКоду(Таб.Область(к,5).Текст);
           ТЗ.НоваяСтрока();
           ТЗ.Позиция        =Товар.Наименование;
           ТЗ.Количество    =Число(Таб.Область(к,4).Текст)*Коэф;
           ТЗ.Цена            =Число(Таб.Область(к,3).Текст);
           ТЗ.Сумма        =ТЗ.Цена*ТЗ.Количество;  
           ТЗ.Продавец        =Таб.Область(Таб.ВысотаТаблицы(),4).Текст;
           Если ТЗ.Продавец="Епур Галина Сергеевна"
           Тогда
               Сообщить(СокрЛП(Путь)+ИмяФайлаНайденного);
           КонецЕсли;
           
           ТЗ.Код             =Таб.Область(к,5);
           ТЗ.Наименование    =Таб.Область(к,1).Текст;
           ТЗ.Дата            =ДатаТекущегоФайла;    
           ТЗ.Позиций         =1;  
           Если к=1
           Тогда
               ТЗ.Скидка=Число(Таб.Область(Таб.ВысотаТаблицы(),5).Текст)*Коэф;
               ТЗ.Чеков=1;
           КонецЕсли; // Учитываем скидку и количество чеков только один раз.


       КонецЦикла;                        
       ИмяФайлаНайденного = ФС.НайтиСледующийФайл();    
       
   КонецЦикла;                        
   
   //Сообщить("Произведён поиск в "+ВсегоЧеков+" чеках за "+ТекДата+"");        

   Возврат ТЗ;
КонецФункции

//*******************************************


Процедура Сформировать()
   Если Число(НачДата)=0 Тогда
       Предупреждение ("Укажите начальную дату!");
       Возврат;                      
   КонецЕсли;                                      
   
   Если Число(НачДата)>Число(КонДата) Тогда
       Предупреждение ("Указанная начальная дата более поздняя, чем указанная конечная дата.");
       Возврат;
   КонецЕсли;
       
   ТЗ=СоздатьОбъект("ТаблицаЗначений");
   ТЗ.НоваяКолонка("Позиция","Справочник.Товар");
   ТЗ.НоваяКолонка("Цена","Число",10,2);
   ТЗ.НоваяКолонка("Количество","Число",10);
   ТЗ.НоваяКолонка("Сумма","Число",10,2);    
   ТЗ.НоваяКолонка("Продавец", "Текст", 50);  
   ТЗ.НоваяКолонка("Код", "Текст", 15);
   ТЗ.НоваяКолонка("Наименование", "Текст", 50);      
   ТЗ.НоваяКолонка("Дата", "Дата");            
   ТЗ.НоваяКолонка("Чеков", "Число");   // эти две


   ТЗ.НоваяКолонка("Позиций", "Число"); // колонки ниже суммируются с помощью метода Свернуть()    

   ТЗ.НоваяКолонка("Скидка", "Число", 10, 2);
       
   Если ПустаяСтрока(Путь1)=0 Тогда ТЗ=ПеребратьЧеки(Путь1, НачДата, КонДата, ТЗ);  КонецЕсли;
   Если ПустаяСтрока(Путь2)=0 Тогда ТЗ=ПеребратьЧеки(Путь2, НачДата, КонДата, ТЗ);  КонецЕсли;
   Если ПустаяСтрока(Путь3)=0 Тогда ТЗ=ПеребратьЧеки(Путь3, НачДата, КонДата, ТЗ);  КонецЕсли;    
   Если ПустаяСтрока(Путь4)=0 Тогда ТЗ=ПеребратьЧеки(Путь4, НачДата, КонДата, ТЗ);  КонецЕсли;    
   Если ПустаяСтрока(Путь5)=0 Тогда ТЗ=ПеребратьЧеки(Путь5, НачДата, КонДата, ТЗ);  КонецЕсли;  
                                                                                             
   ТЗ.Свернуть("Дата,Продавец", "Количество,Сумма,Чеков,Позиций,Скидка"); // сложить повторяшки                                                                      

   ТЗ.Сортировать("+Дата,+Продавец");    // сортируем ТЗ сначала по дате, а потом по ФИО продавца

   
   Если ТЗ.КоличествоСтрок()>0
   Тогда
       Отчёт=СоздатьОбъект("Таблица");
       Отчёт.ИсходнаяТаблица("Таблица");
       Отчёт.ВывестиСекцию("Шапка");            
         
       ТекДата=ТЗ.ПолучитьЗначение(1, "Дата");
       Отчёт.ВывестиСекцию("День");      
       
       ТЗ.ВыбратьСтроки();
       Пока ТЗ.ПолучитьСтроку()=1
       Цикл        
           
           Если ТекДата<>ТЗ.ПолучитьЗначение(ТЗ.НомерСтроки, "Дата")
           Тогда        
                  ТекДата=ТЗ.ПолучитьЗначение(ТЗ.НомерСтроки, "Дата");      
                  Отчёт.ВывестиСекцию("День");        
           КонецЕсли;
               
           Отчёт.ВывестиСекцию("Строка");      
       КонецЦикла;              
   КонецЕсли;                          
   
   // Подведение итогов за период


   Отчёт.ВывестиСекцию("Итого");        
   ТЗ.Свернуть("Продавец", "Количество,Сумма,Чеков,Позиций,Скидка"); // подведение итогов за период, сворачивание по имени продавца


   ТЗ.Сортировать("+Продавец");
   ТЗ.ВыбратьСтроки();
   Пока ТЗ.ПолучитьСтроку()=1 цикл        
       Отчёт.ВывестиСекцию("Строка");      
   КонецЦикла;            
                                       
   Отчёт.Показать();
КонецПроцедуры
               
// Все пути должны быть с закрывающим \ !!!


Путь1="\\s\o\Кассир1\";
Путь2="\\s\o\Кассир2\";
Путь3="\\s\o\Кассир4\";
Путь4="\\p\o\Кассир3\";
Путь5="\\s\o\КассирМ1\";
Заголовок="Имя фирмы";
44 Злопчинский
 
30.11.11
17:52
Что такое UUUUVVLL = формат записи даты, удобный для нормальной человеческой сортировки по именам файлов - имена файлов следует именовать не ДДММГГ, а ГГГГММДД
45 Злопчинский
 
30.11.11
17:53
(41) по (39)
а почему это у тебя в выборке по ФС - короткие имена файлов..?
46 kkursor
 
30.11.11
18:35
(45) все файлы перелопачивать он будет ОООООООООЧЕНЬ долго. Там в каждой папке их тысяч по 20. А их 5.
Задумался. Как отдумается - отпишу, чем кончилось.
47 Rie
 
30.11.11
19:35
(45) По идее, под маску - должны попадать и короткие.
48 kkursor
 
30.11.11
19:45
Злопчинский, действительно ничего лишнего не попадает. О чём это говорит?
Кстати, а насчёт частичного перекрывания в формате 8.3 идея. 271111~1.MXL, 2711111~2.MXL... А если их не 10 с одинаковыми номерами в начале, а 100? Что в таком случае происходит с именем в формате 8.3?
Хотя тогда были бы массовые подобные случаи, а не единичные.
49 Rie
 
30.11.11
19:47
(48) А посмотри :-)
50 Злопчинский
 
30.11.11
21:15
(48) это ты мой предложенный код впиндюрил наконец? или что?
.
даже 20тыс файлов - херня для пройтись один раз, а не 30 раз как у тебя в оригинальном алгоритме...
.
ну как разберешься.. разложи уже в иерархию по папочкам год-месяц-день..
51 Злопчинский
 
30.11.11
21:16
(48) это говорит о том, что извращаться надо там, где без извращенйи не обойтись - в борделе, например. А если хочешь чтобы программа работала предсказуемо - пиш и максимально простые линейные алгоритмы..
52 Mr_Rm
 
30.11.11
22:03
Код в (43) не отличается принципиально от (8) - в обоих случаях проверяется на соответствие дате имя файла уже попавшего в выборку. Но нет ответа, почему в нее попадает ненужный файл.

Что выведет такой вариант:
   Пока ИмяФайлаНайденного<>""
   Цикл
       Сообщить(ИмяФайлаНайденного)

Что выведет в шелле для соответствующего каталога
dir 271111*.mxl

Нет ли ошибки файловой системы?
53 Злопчинский
 
30.11.11
22:28
(52) совсем опупел "не отличается принципиально"..? если насчет соответствия дата-имя - то да, нового ту не придумал. но по крайней мере в (43) по списку файлов пробегается 1 раз; и при размере списка в 20 тыс - соспоставляется 20 тыс раз имя-дата, в (8) - за месяц если брать - выборка файлов пробегается 30 раз, то есть вместо 20 тыс осматривается 600 тыс.. - мне кажется разница достаточно емкая/принципиальная..
54 Злопчинский
 
30.11.11
22:30
"...почему в нее попадает ненужный файл" - автор так внятно и не дал инфу - коротке имя файла или полное имя файла... хз..
.
а из фразы в (48) "..действительно ничего лишнего не попадает." - можно протелепатировать что автор запустил код из (43) и никаких кривых данных не получил... о чем это говорит.. - скорее всего о кривизне в исходных алгоритмах и подходу к программированию.. хотя на 100% скидывать трабл конечно нельзя.. но япочему-то думаю, что разпо коду (43) проблем не наблюдается - то вопросы не в файловой системе, а в коде...
55 Mr_Rm
 
30.11.11
23:17
(53) По поводу размера выборки.
В (43) есть ошибка:
 ИмяФайлаНайденного = ФС.НайтиПервыйФайл(+"*.mxl");

Если имелось в виду
 ИмяФайлаНайденного = ФС.НайтиПервыйФайл("*.mxl");

то в выборку попадут все 20 тыс. файлов, и будет 20 тыс. повторов цикла.

Если же работал бы вариант ТС с маской "271111*.mxl", то в выборку попали ли бы только файлы за нужную дату, около сотни (см. (24)). И даже для месяца будет примерно 100*30 повторов.
56 Злопчинский
 
30.11.11
23:54
(55) возможно был я неправ в рассмотрении вопроса
один хрен сделать 30 выборок с маской по каждой дате или одну выборку последовательно.
.
а тут выясняется что в папке лежит кучей все - и относящееся и не относячщееся к анализируемому периоду... конечно, когда в папке свалено все кучей - представляется целесооборзаным разумно ограничить перебор более узкой маской, в этом случае алгоритм подобный (8) более предпочтителен...
57 medved_kot
 
01.12.11
15:30
ппп = "";
еее = "\\s\o\Кассир1\"
ФС.ВыбратьФайл(0, ппп, еее,,"271111*.mxl|271111*.mxl");

Такой код тоже показывает файлы с 270511*.mxl?
58 filh
 
01.12.11
15:31
(57) а проверить?
59 Rie
 
01.12.11
15:32
(58) А ветку почитать?
60 medved_kot
 
01.12.11
15:33
(58) у меня нет такого кол-ва файлов, поэтому и прошу автора проверить.
(да ; во второй строке нет.)
61 filh
 
01.12.11
15:34
(59) да уже
:)
Закон Брукера: Даже маленькая практика стоит большой теории.