Имя: Пароль:
1C
1C 7.7
v7: Сравнение Кодов Номенклатуры
,
0 MixanM
 
08.12.11
05:41
В процессе работы, возникла задача по срвнению кода номенклатуры, вообщем раньше вели учет ТиС в 2х разных базах, и соотвесвенно там создавали код, и наименование номенкалтуры, уто во что горазд. Сейчас решили объеденить коды и названия.Т.к. нужно сделать разово, ршил не делать через ОЛЕ. Решил сделать так, выгрузить номенкалтуру из одной базы в файл:
Процедура Сформировать()
   Перем Запрос, ТекстЗапроса, Таб;
   //Создание объекта типа Запрос
   Запрос = СоздатьОбъект("Запрос");
   ТекстЗапроса =
   "//{{ЗАПРОС(Сформировать)
   |ОбрабатыватьДокументы все;
   |Обрабатывать НеПомеченныеНаУдаление;
   |Номенклатура = Справочник.Номенклатура.ТекущийЭлемент;
   |Группировка Номенклатура упорядочить по Номенклатура.Код, Номенклатура.Наименование;
   |"//}}ЗАПРОС
   ;
   Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
       Возврат;
   КонецЕсли;
    Таб = СоздатьОбъект("ТаблицаЗначений");
    Таб.НоваяКолонка("Код");
    Запрос.Выгрузить(Таб);
    ЗначениеВФайл("c:\tab.txt", Таб, 0);
КонецПроцедуры

И загрузить этот файл в другую базу и проверить "персечение" кодов :

   Тз = СоздатьОбъект("ТаблицаЗначений");
   ЗначениеИзФайла("C:\tab.txt", Тз);
   
   Спр=СоздатьОбъект("Справочник.Номенклатура");
   Спр.ВыбратьЭлементы();
   Пока Спр.ПолучитьЭлемент()=1 Цикл
       Если Спр.ЭтоГруппа()=1 Тогда //группы оставляем
           Продолжить;
       КонецЕсли;
       Если ТЗ.НайтиЗначение(Спр.Код, "Код", 0)= 1 Тогда  
           Сообщить("Найден дубль : "+Тз.ТекущаяСтрока())
       КонецЕсли;
   КонецЦикла;
Но такая проблемма, у меня при обработке, 1с выпиливается с ошибкой (
1 GreyK
 
08.12.11
05:53
(0) Выгружай в таблицу код, наименование и признак группы, тогда увидишь значения.
2 MixanM
 
08.12.11
06:22
(1) т.е. перед выгрузкой в файл, делать поиск по коду,выгрузку в ТЗ, и потом уже в файл ?
3 GreyK
 
08.12.11
06:43
Примерно так:

   Запрос = СоздатьОбъект("Запрос");
   ТекстЗапроса =
   "//{{ЗАПРОС(Сформировать)
   |Код = Справочник.Номенклатура.Код;
   |Наименование = Справочник.Номенклатура.Наименование;
   |Родитель = Справочник.Номенклатура.Родитель;
   |ТекущийЭлемент = Справочник.Номенклатура.ТекущийЭлемент;
   |Группировка ТекущийЭлемент;
   |"//}}ЗАПРОС


   ;
   // Если ошибка в запросе, то выход из процедуры
   Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
       Возврат;
   КонецЕсли;
   Таб = СоздатьОбъект("ТаблицаЗначений");
   Запрос.Выгрузить(Таб);
   Таб.НоваяКолонка("ЭтоГруппа");
   Таб.ВыбратьСтроки();
   Пока Таб.ПолучитьСтроку()=1 Цикл
       Таб.ЭтоГруппа = ТекущийЭлемент.ЭтоГруппа;
   КонецЦикла;
   ЗначениеВФайл("c:\tab.txt", Таб, 0);


Но я-бы делал по ОЛЕ.
4 MixanM
 
08.12.11
06:50
(3) Я вот тоже склоняюсь в сторону ОЛЕ, если не заработает через файл, то буду через ОЛЕ
5 MixanM
 
08.12.11
06:58
(3) Код немного не рабочий, ругается на переменную "ТекущийЭлемент" - переменная не определена
6 GreyK
 
08.12.11
07:12
(5)        
Таб.ЭтоГруппа = Таб.ТекущийЭлемент.ЭтоГруппа;
7 MixanM
 
08.12.11
07:41
Спс, я уже понял ))
8 MixanM
 
08.12.11
07:59
Сделал через ОЛЕ, токма 1с  в поле сообщения сообщает "ОЛЕ ОЛЕ ОЛЕ" и так до конца, может эска футбольный фанат ?

Процедура Сформировать()
   Спр = СоздатьОбъект("Справочник.Номенклатура");
   БазаОле=СоздатьОбъект("V77.Application");
   КаталогБазыОЛе  = "H:\Config\Trade_lider\";
   ПользовательОле = "Admin";
   ПарольОле       = "";
   ЗапускБезЗаставки = 1;
   РезультатПодключения = БазаОле.Initialize(БазаОле.RMTrade, "/DH:\Config\Trade_torg\","NO_SPLASH_SHOW");
   Если РезультатПодключения = 0 Тогда
       Сообщить("Не удалось подключится к указанной базе - проверьте вводные!");
   Иначе
       Сообщить("Коннект был устновлен");
   КонецЕсли;
   СпрОЛЕ = БазаОле.CreateObject("Справочник.Номенклатура");
   СпрОЛЕ.ВыбратьЭлементы() ;
   Спр.ВыбратьЭлементы();
   Пока Спр.ПолучитьЭлемент()=1 Цикл
       Если Спр.ЭтоГруппа()=1 Тогда //группы оставляем
           Продолжить;
       КонецЕсли;
       
       Если СпрОЛЕ.НайтиПоКоду(Спр.Код, 0) = 1 Тогда  
           Сообщить(СпрОЛЕ.ТекущийЭлемент());
       КонецЕсли;    
   КонецЦикла;
КонецПроцедуры
9 Mikeware
 
08.12.11
08:25
(8) Нет, это известная проблема. Она возникает у отдельных людей. А корень проблемы в плохой ДНК, либо в соотношении радиусов.
10 MixanM
 
08.12.11
08:30
(9) Тонко )
11 GreyK
 
08.12.11
08:39
(8) По ОЛЕ только текст, число, дата.
Твоя задача, насколько я понимаю, найти по наименованию и сравнить коды, сделать это лучше через ТЗ на форме. Если что-то не находится по наименованию, то юзверь должен выбрать из справочника анналог, если он есть.
12 Mikeware
 
08.12.11
08:40
(10) И, что самое характерное, точно...
13 MixanM
 
08.12.11
08:42
Мне просто надо найти расхождения по коду
14 MixanM
 
08.12.11
08:42
т.е лучше это сделать через ТЗ ?
15 MixanM
 
08.12.11
08:44
я сделал так, неужт не правиьно ? :
Процедура Сформировать()
   Спр = СоздатьОбъект("Справочник.Номенклатура");
   БазаОле=СоздатьОбъект("V77.Application");
   КаталогБазыОЛе  = "H:\Config\Trade_lider\";
   ПользовательОле = "Admin";
   ПарольОле       = "";
   ЗапускБезЗаставки = 1;
   РезультатПодключения = БазаОле.Initialize(БазаОле.RMTrade, "/DH:\Config\Trade_torg\","NO_SPLASH_SHOW");
   Если РезультатПодключения = 0 Тогда
       Сообщить("Не удалось подключится к указанной базе - проверьте вводные!");
   Иначе
       Сообщить("Коннект был устновлен");
   КонецЕсли;
   СпрОЛЕ = БазаОле.CreateObject("Справочник.Номенклатура");
   СпрОЛЕ.ВыбратьЭлементы() ;
   Спр.ВыбратьЭлементы();
   Счетчик = 0;
   Пока СпрОЛЕ.ПолучитьЭлемент() = 1 Цикл
       Если СпрОЛЕ.ЭтоГруппа() = 0 Тогда
           КодСравнения = СпрОЛЕ.Код;
           Если Спр.НайтиПоКоду(КодСравнения) = 1 Тогда
               Спр.ТекущийЭлемент();
               КодТорг = СпрОЛЕ.Код;
               КодЛидер = Спр.Код;
               Если (КодТорг <> КодЛидер) Тогда  
                   Счетчик = Счетчик + 1;
                   Сообщить(""+Счетчик+" : Расхождение");
                   Сообщить("в Базе торг :" + КодТорг + " В базе Лмдер :" + КодЛидер);
               КонецЕсли;
           КонецЕсли;
           
       КонецЕсли;
       Сообщить("Всего расхождений :" +Счетчик);
   КонецЦикла;    
КонецПроцедуры
16 GreyK
 
08.12.11
08:45
(14) ТЗ на форме обработки, в неё загружены коды и наименования другой базы, и ещё две колонки с кодом и номенклатурой текущей базы.
17 GreyK
 
08.12.11
08:46
(15) Не правильно.
18 MixanM
 
08.12.11
08:51
(17) а что не правильно ? вроде сравнил по коду, ежели нет то идем дальше
19 GreyK
 
08.12.11
08:54
(18) То, что в двух базах есть одинакрвые коды, не означает, что они присвоенны одинаковым товарам.
20 MixanM
 
08.12.11
08:57
(19) так в том то и дело, что нужно найти дубли кода, если они есть, и не важно, аналогичный там товар, или нет( что вероятней на 99%)
21 MixanM
 
08.12.11
08:58
Базы велись в разных фирмах, cqxfc происходит слияние, все коды приводятся к единому виду, взята за основу 1 база, и если есть совпадения по коду, номенклаьтура будет проверяться, но это другая история, на данном этапе, нужно прсто выловить одинаковые коды
22 Ёпрст
 
08.12.11
09:18
http://zalil.ru/32224611

наслаждайся
23 Эльниньо
 
08.12.11
11:26
Сохраняешь в одном формате. Читаешь в другом.
24 Эльниньо
 
08.12.11
12:05
+(23)
ЗначениеВФайл("c:\tab.txt", Таб, 0); // здесь 0

ЗначениеИзФайла("C:\tab.txt", Тз); // по умолчанию - 1

Вылет Эсины гарантирован.
25 MixanM
 
09.12.11
07:03
(24) это имя перменной разный, а тип у них одинаковый, неужели мя переменной так важно ?
26 MixanM
 
09.12.11
07:17
Хотя пох, уже пятницо
27 Эльниньо
 
09.12.11
09:55
ЗначениеВФайл(<ИмяФайла>,<Объект>,<Формат>)
Назначение:
Сохраняет значение объекта в файле.
Возвращает: 1 - функция выполнена успешно; 0 - функция не выполнена.
Параметры:
<ИмяФайла> - имя файла.
<Объект> - значение, которое следует сохранить в файле.
<Формат> - необязательный параметр. Число: 1 - сохранение во внутреннем формате; иначе во внешнем. Значение по умолчанию: 1.

Внимательно смотрим 3-й параметр.
28 MixanM
 
13.12.11
06:24
сдела через ОЛЕ, скажите как сделать :при нахождении совпадающих кодов в Справоничк.Номенклатура", сделать поиск и сравнение по коду в подчиненых справочниках текущего элемента, сдела вот так:

Процедура Сформировать()
   Спр = СоздатьОбъект("Справочник.Номенклатура");
   СпрЕдиницы = СоздатьОбъект("Справочник.Единицы");
   Файл = СоздатьОбъект("Текст");
   ИмяФайла = "c:\rash.txt";
   Файл.Открыть(ИмяФайла);
   БазаОле=СоздатьОбъект("V77.Application");
   ПользовательОле = "Admin";
   ПарольОле       = "";
   ЗапускБезЗаставки = 1;
   ...
   СпрОЛЕ = БазаОле.CreateObject("Справочник.Номенклатура");
   СпрОлЕЕдиницы = БазаОле.CreateObject("Справочник.Единицы");
   СпрОЛЕ.ВыбратьЭлементы() ;
   Спр.ВыбратьЭлементы();
   Счетчик = 0;
   Пока СпрОЛЕ.ПолучитьЭлемент() = 1 Цикл
       КодСравнения = СпрОЛЕ.Код;
       Если Спр.НайтиПоКоду(КодСравнения, 0) = 1 Тогда
           НайденныйЭлемент = Спр.ТекущийЭлемент();
           КодВПереферийн = СпрОЛЕ.Код;
           КодВБазе = НайденныйЭлемент.Код;
           Если (КодВБазе = КодВПереферийн) Тогда  
               СпрЕдиницы.ИспользоватьВладельца(НайденныйЭлемент);
               СпрЕдиницы.ВыбратьЭлементы();
               СпрОлЕЕдиницы.ИспользоватьВладельца(СпрОле.ТекущийЭлемент());
               СпрОлЕЕдиницы.ВыбратьЭлементы();
               Пока СпрОлЕЕдиницы.ПолучитьЭлемент() = 1 Цикл
                   КодОлеЕдиницы = СпрОлЕЕдиницы.Код;
                   Если СпрЕдиницы.НайтиПоКоду(КодОЛЕЕдиницы, 0) = 1 Тогда
                       НайденныйЭлементЕдиницы = СпрЕдиницы.ТекущийЭлемент();
                       КодЕдиницыВОЛЕ = СпрОлЕЕдиницы.Код;
                       КодвЕдиницах = НайденныйЭлементЕдиницы.Код;              
                       Если (КодВБазе <> КодЕдиницыВОЛЕ) Тогда
                           Счетчик = Счетчик + 1;
                           Файл.КоличествоСтрок();
                           НомерСтроки = Файл.КоличествоСтрок() + 1;
                           Файл.ДобавитьСтроку(КодВБазе+" : с : "+ КодВПереферийн);
                           Сообщить("Найдены элементы : "+КодВПереферийн+", и  : "+КодВБазе);
                           Файл.Записать(ИмяФайла);
                       КонецЕсли;
                   КонецЕсли;
               КонецЦикла;        
           КонецЕсли;
       КонецЕсли;
       Сообщить("Всего расхождений :" +Счетчик);
   КонецЦикла;    
КонецПроцедуры
Не работает, т.е он чего то ищет, но не записывает в файл не соотвествия,
было так, все работает, ищет схожие коды и сообщает их :
Пока СпрОЛЕ.ПолучитьЭлемент() = 1 Цикл
       КодСравнения = СпрОЛЕ.Код;
       Если Спр.НайтиПоКоду(КодСравнения, 0) = 1 Тогда
           НайденныйЭлемент = Спр.ТекущийЭлемент();
           КодВПереферийн = СпрОЛЕ.Код;
           КодВБазе = НайденныйЭлемент.Код;
           Если (КодВБазе = КодВПереферийн) Тогда  
               Счетчик = Счетчик + 1;
               Файл.КоличествоСтрок();
               НомерСтроки = Файл.КоличествоСтрок() + 1;
               Файл.ДобавитьСтроку(КодВБазе+" : с : "+ КодВПереферийн);
               Сообщить("Найдены элементы : "+КодВПереферийн+", и  : "+КодВБазе);
               Файл.Записать(ИмяФайла);    
           КонецЕсли;
       КонецЕсли;
       Сообщить("Всего расхождений :" +Счетчик);
   КонецЦикла;    
КонецПроцедуры
29 MixanM
 
13.12.11
06:32
А все, нашел в чем косяк, всем спасибо
30 Злопчинский
 
13.12.11
07:09
(28) ненавижу этажерки если, когда можно код сделать практически "линейным"
31 echo77
 
13.12.11
07:10
я бы из двух баз выгрузил номенклатуру и сравнил был их в excel.
- Если списки не очень большие(<200К записей)
32 MixanM
 
13.12.11
07:19
(31), дело в том, что сейчас столкнулся с тем, что для проверки на соотвесвтие - можно использовать подчиненный справочник Единицы, т.е. код у номенклатуры одинаков, но для проверки скажем наименования, можно использовать штрих код, который хранится в справочнике "Единицы", сделал так, 1с возвращат ошибку ( (30) - полностью согласен ) :
Пока СпрОЛЕ.ПолучитьЭлемент() = 1 Цикл
           КодСравнения = СпрОЛЕ.Код;
           Если Спр.НайтиПоКоду(КодСравнения, 0) = 1 Тогда
               НайденныйЭлемент = Спр.ТекущийЭлемент();
               КодВПереферийн = СпрОЛЕ.Код;
               КодВБазе = НайденныйЭлемент.Код;
               Если (КодВБазе = КодВПереферийн) Тогда  
                   Счетчик = Счетчик + 1;            
                   //Сообщить(""+Счетчик+" : Расхождение");
                   //Файл.ДобавитьСтроку(КодВБазе+";"+ КодВПереферийн);
                   //    Сообщить("Найдены элементы : "+КодВПереферийн+", и  : "+КодВБазе);
                   //Файл.Записать(ИмяФайла);
                   СпрЕдиницы.ИспользоватьВладельца(Спр.ТекущийЭлемент());
                   Если Спр.НайтиПоКоду(КодВБазе) = 1 Тогда
                       НайденныйКод = СпрЕдиницы.ТекущийЭлемент();
                   КонецЕсли;
                   СпрЕдиницыОЛЕ.ИспользоватьВладельца(СпрОЛЕ.ТекущийЭлемент());
                   Если СпрОЛЕ.НайтиПоКоду(КодВПереферийн) = 1 Тогда
                       НайденныйКодОЛЕ = СпрЕдиницыОЛЕ.ТекущийЭлемент();
                   КонецЕсли;
                   Если (НайденныйКод = НайденныйКодОЛЕ) Тогда
                       Сообщить(НайденныйКодОЛЕ+НайденныйКодОЛЕ);
                   КонецЕсли;
               КонецЕсли;
           КонецЕсли;
       Сообщить("Всего расхождений :" +Счетчик);
   КонецЦикла;
КонецПроцедуры
33 MixanM
 
13.12.11
07:25
(30) Кст насчет этажерок, :
выбираем код из справочника
сравниваем с кодами из другого справочника
 если нашли, берем элементы подчиненного справочника, текущего элемента основной базы и ыбираем оттуда коды
  берем элементы из подчиненого справочника, с которой сравниваем базы,
   сравниваем найденные элементы подчиненных справочников
и обратно, вот поэжтому то и этажерка =(
34 MixanM
 
13.12.11
07:48
т.к. ОЛЕ не может работать с методом ТекущийЭлемент(), исправил все на :
   СпрЕдиницыОЛЕ = БазаОле.CreateObject("Справочник.Единицы");
   СпрОЛЕ = БазаОле.CreateObject("Справочник.Номенклатура");
   СпрОЛЕ.ВыбратьЭлементы() ;
   Спр.ВыбратьЭлементы();
   Счетчик = 0;
   Попытка
   Пока СпрОЛЕ.ПолучитьЭлемент() = 1 Цикл
           КодСравнения = СпрОЛЕ.Код;
           Если Спр.НайтиПоКоду(КодСравнения, 0) = 1 Тогда
               НайденныйЭлемент = Спр.ТекущийЭлемент();
               КодВПереферийн = СпрОЛЕ.Код;
               КодВБазе = НайденныйЭлемент.Код;
               Если (КодВБазе = КодВПереферийн) Тогда  
                   Счетчик = Счетчик + 1;            
                   //Сообщить(""+Счетчик+" : Расхождение");
                   //Файл.ДобавитьСтроку(КодВБазе+";"+ КодВПереферийн);
                   //    Сообщить("Найдены элементы : "+КодВПереферийн+", и  : "+КодВБазе);
                   //Файл.Записать(ИмяФайла);
                   
                   СпрЕдиницы.ИспользоватьВладельца(Спр.ТекущийЭлемент());
                   Если Спр.НайтиПоКоду(КодВБазе, 0) = 1 Тогда
                       НайденныйКод = СпрЕдиницы.ТекущийЭлемент().ШтрихКод;
                   КонецЕсли;
                   
                   СпрЕдиницыОЛЕ.ИспользоватьВладельца(СпрОЛЕ.НайтиПоКоду(КодВПереферийн), 0);
                   Если СпрОЛЕ.НайтиПоКоду(КодВПереферийн) = 1 Тогда
                       НайденныйКодОЛЕ = СпрЕдиницыОЛЕ.ШтрихКод
                   КонецЕсли;
                   Если (НайденныйКод = НайденныйКодОЛЕ) Тогда
                       Сообщить(НайденныйКодОЛЕ+НайденныйКодОЛЕ);
                   КонецЕсли;
               КонецЕсли;
           КонецЕсли;
       Сообщить("Всего расхождений :" +Счетчик);
   КонецЦикла;

Исключение
   Предупреждение( ОписаниеОшибки());
   Возврат;
КонецПопытки;    
КонецПроцедуры
Пишет "Не выбран Элемент (строка : Пока СпрОЛЕ.ПолучитьЭлемент() = 1 Цикл)"
35 Ёпрст
 
13.12.11
09:22
(34)
>>> СпрЕдиницыОЛЕ.ИспользоватьВладельца(СпрОЛЕ.НайтиПоКоду(КодВПереферийн), 0);

Это полный ПЭ.

Всё в топку, и читать СП на ночь.
36 MixanM
 
13.12.11
10:21
(35) так епрстэ, я его и курю по ОЛЕ, токма там нет типвых примеров, все какие то простые (. Вот как мля сравнить 2 выбранного элемента, элементы в подчиненном справочнике?
37 MixanM
 
13.12.11
10:32
Херню опять написал, вообщем, Если нашел элемент в "Номенклатуре" Справочника текущей базы который равен Элементу "Номенклатуры" в переферийной базе, Тогда смотреть в подчиненом справчонике Текущей Базы "Еденицы" Код элепмента и сравнить его с Кодом в Справчонике "Единицы" в переферином справчонике текущего элемента.. пи№;%ц просто....
38 Ёпрст
 
13.12.11
10:34
Я тебе дал  ответ в 22, разбирайся
39 Ёпрст
 
13.12.11
10:35
А то что ты пишешь, даже в текущей базе работать не будет. Оля тут не при чем, тут с самыми основами косяк - отсутствуют элементарные знания методов работы со справочниками.
40 Mikeware
 
13.12.11
10:36
(39) Просто соотношение радиусов такое....
41 MixanM
 
13.12.11
10:36
(40) ... забыли добавить - троллфейс.джипег
Проблемы невозможно решaть нa том же уровне компетентности, нa котором они возникaют. Альберт Эйнштейн