Имя: Пароль:
1C
1С v8
Вернуть массив из функции.
0 S3rGotcha
 
22.04.15
11:23
Только начинаю осваивать 1С. Столкнулся с проблемой:

Есть строка вида: СТР="Префикс1=Значение1;Префикс2=Значение2..."
Есть массив префиксов: МассивПрефиков = {Префикс1=, Префикс2=, ...}
Есть процедура, где строку разбивают на массив вида
ИсходныйМассив = {Префикс1=Значение1, Префикс2=Значение2, ...}
Далее в процедуре вызывается функция, на вход ей подаются элементы массива ИсходныйМассив и весь МассивПрефиксов. Задача функции - вернуть ВыходнойМассив вида {Префикс1, Значение1} (конечно попутно там происходит проверка еще кое-каких условий, но ВыходнойМассив должен отдаваться с 2 значениями). По факту получаю:
Вызываю в основной процедуре эту функцию:

Результат=Функция(ИсходныйМассив[элемент], МассивПрефиксов);
Для каждого ЭлементРезультат из Результат Цикл
   Сообщить(ЭлементРезультат);
КонецЦикла

Заканчивается ошибкой: итератор для значения не определен

Результат=Функция(ИсходныйМассив[элемент], МассивПрефиксов);
   Сообщить(Результат[0]);

Заканчивается ошибкой: Получение элемента по индексу для значения не определено

Отсюда вопрос: в чем я не прав?
1 ДенисЧ
 
22.04.15
11:24
Не вижу оператора Возврат в функции
2 ДенисЧ
 
22.04.15
11:24
Кроме того - всегда есть отладчик, в котором можно посмотреть на тип результатат
3 Ненавижу 1С
 
гуру
22.04.15
11:31
ВыходнойМассив должен отдаваться с 2 значениями

это называется Структура или Соответствие, на крайний случай таблица значений или список значений
4 S3rGotcha
 
22.04.15
11:34
(1) Оператор возврат есть. Выглядит он вот так:

Возврат ВыходнойМассив;

Значения в выходной массив предварительно задаются так:
ВыходнойМассив.Добавить(ПервыйЭлемент);
ВыходнойМассив.Добавить(ВторойЭлемент);
5 Гёдза
 
22.04.15
11:35
покажи полный код
6 ДенисЧ
 
22.04.15
11:39
(4) Отлично. Теперь переходи ко второму пункту
7 S3rGotcha
 
22.04.15
11:42
Это функция:

Функция ВыборАтрибутов(МассивАтрибутов, ЗаписьВСтроке) Экспорт    
    ВыходнойМассив = Новый Массив;
    Если МассивАтрибутов = Неопределено Тогда
        Сообщить("Массив префиксов не определен!");
    КонецЕсли;
    Для ИндексПрефикса = 0 По МассивАтрибутов.ВГраница() Цикл
        Если  (Найти(ЗаписьВСтроке, МассивАтрибутов[ИндексПрефикса])>0 и СравнитьПервыеСимволы(ЗаписьВСтроке, МассивАтрибутов[ИндексПрефикса])>0) Тогда
            ЗаписьЗначение = СтрЗаменить(ЗаписьВСтроке,МассивАтрибутов[ИндексПрефикса],"");
            ФорматированныйАтрибут = СтрЗаменить(СтрЗаменить(МассивАтрибутов[ИндексПрефикса],"=","")," ",""); //отрезаем позможные пробелы и знак "="
            ВыходнойМассив.Добавить(ФорматированныйАтрибут);
            ВыходнойМассив.Добавить(ЗаписьЗначение);
            ИндексПрефикса = ИндексПрефикса + 1;
            Сообщить("Функция ВыборАтрибутов. Выходое значение 0: "+ВыходнойМассив[0]);
            Сообщить("Функция ВыборАтрибутов. Выходое значение 1: "+ВыходнойМассив[1]);
            Возврат ВыходнойМассив;
        КонецЕсли;
    КонецЦикла;
КонецФункции


Это процедура:

Процедура Кнопка1Нажатие(Элемент)
    
    
    МассивПрефиксов = Новый Массив();
        МассивПрефиксов.Добавить("Параметр1=");
        МассивПрефиксов.Добавить("Параметр2=");
        МассивПрефиксов.Добавить("Параметр3=");
        
        Строка = "Параметр1=Значение1;Параметр2=Значение2;Параметр3=Значение3"; // получить стрoку с указанным номером и преобразуем её в массив
        МассивСтроки = РазбитьСтроку(Строка,";");// процедура из типовой конфигурации, разбивает строку в массив по разделителям
        ///////////////////////
        Для а=0 по МассивСтроки.ВГраница() цикл
            Сообщить("Индекс: "+а+" Значение: "+МассивСтроки[а]);
            СТР=ВыборАтрибутов(МассивПрефиксов,МассивСтроки[а]);
            Сообщить(СТР[0]);
        КонецЦикла;
    
КонецПроцедуры
8 asady
 
22.04.15
11:44
Функция ВыборАтрибутов(МассивАтрибутов, ЗаписьВСтроке) Экспорт    
    ВыходнойМассив = Новый Массив;
    Если МассивАтрибутов = Неопределено Тогда
        Сообщить("Массив префиксов не определен!");
    КонецЕсли;
    Для ИндексПрефикса = 0 По МассивАтрибутов.ВГраница() Цикл
        Если  (Найти(ЗаписьВСтроке, МассивАтрибутов[ИндексПрефикса])>0 и СравнитьПервыеСимволы(ЗаписьВСтроке, МассивАтрибутов[ИндексПрефикса])>0) Тогда
            ЗаписьЗначение = СтрЗаменить(ЗаписьВСтроке,МассивАтрибутов[ИндексПрефикса],"");
            ФорматированныйАтрибут = СтрЗаменить(СтрЗаменить(МассивАтрибутов[ИндексПрефикса],"=","")," ","");//отрезаем позможные пробелы и знак "="

            ВыходнойМассив.Добавить(ФорматированныйАтрибут);
            ВыходнойМассив.Добавить(ЗаписьЗначение);
            ИндексПрефикса = ИндексПрефикса + 1;
            Сообщить("Функция ВыборАтрибутов. Выходое значение 0: "+ВыходнойМассив[0]);
            Сообщить("Функция ВыборАтрибутов. Выходое значение 1: "+ВыходнойМассив[1]);
            Возврат ВыходнойМассив;
        КонецЕсли;
    КонецЦикла;
Возврат ВыходнойМассив; // ну на всякий случай :))))
КонецФункции
9 S3rGotcha
 
22.04.15
11:47
(8) Тогда пишет: Индекс находится за границами массива
10 asady
 
22.04.15
11:48
(9) дальше уже сам догадаешься?
11 S3rGotcha
 
22.04.15
11:49
(10) увы, нет.
12 asady
 
22.04.15
11:53
(11) у тебя условие    (Найти(ЗаписьВСтроке, МассивАтрибутов[ИндексПрефикса])>0 и СравнитьПервыеСимволы(ЗаписьВСтроке, МассивАтрибутов[ИндексПрефикса])>0)

никогда не ИСТИНА
13 asady
 
22.04.15
11:55
(12)+
а почему знаешь?
14 S3rGotcha
 
22.04.15
11:56
(12) Забыл еще 1 функцию. Сейчас:

Функция СравнитьПервыеСимволы(Знач ЗаписьВСтроке, Знач Атрибут) Экспорт
    Если (Лев(ЗаписьВСтроке,9) = Лев(Атрибут,9)) Тогда
        Возврат 1;
    КонецЕсли;
    Возврат 0;
КонецФункции
15 S3rGotcha
 
22.04.15
11:58
(13) судя по тому, что в основной функции в качестве маркера я использую:

Сообщить("Функция ВыборАтрибутов. Выходое значение 0: "+ВыходнойМассив[0]);
Сообщить("Функция ВыборАтрибутов. Выходое значение 1: "+ВыходнойМассив[1]);

И вижу вывод, то условие-таки выполняется. Разве нет?
16 asady
 
22.04.15
12:00
(15) ИндексПрефикса = ИндексПрефикса + 1;
вот это зачем?
17 S3rGotcha
 
22.04.15
12:02
(16) а как по массиву атрибутов двигаться? )) Я далек от программирования. Использовал классический цикл for для массива. Вроде верно?
18 Лесной
 
22.04.15
12:09
Типы = Новый Массив(2,2);
Типы[0][0] = "WI";    Типы[0][1] = 9;
Типы[1][0] = "WO";    Типы[1][1] = 8;
Для И = 0 по 1 Цикл
    Для Е = 0 по 1 Цикл
        Сообщить(Типы[И][Е]);
    КонецЦикла;
КонецЦикла;
19 Лесной
 
22.04.15
12:13
ой, я чета попутал. Пардонте...
20 asady
 
22.04.15
12:22
(17) а где ты в цикле for  видел инкрементацию переменной цикла
21 1Сергей
 
22.04.15
12:27
(20) в С++ третим параметром :)
22 S3rGotcha
 
22.04.15
12:27
(20) for ( int counter = 0; counter < 15; counter++)
23 1Сергей
 
22.04.15
12:28
(22) в 1С не надо этого делать. Тут Для...Цикл сам делает ++
24 asady
 
22.04.15
12:28
(22) это конструкция языка - это другое.

где ты видел инкрементацию переменной цикла в теле цикла?
25 S3rGotcha
 
22.04.15
12:30
(24) ну я просто по аналогии решил сделать. Раз в условиях нельзя задать - задал в теле цикла после выполнения. Яжнезнал ))
26 1Сергей
 
22.04.15
12:33
(25) Язык 1С - это "бейсик, переведённый промтом", а не Си
27 asady
 
22.04.15
12:33
ункция ВыборАтрибутов(МассивАтрибутов, ЗаписьВСтроке) Экспорт    
    ВыходнойМассив = Новый Массив;
    Если МассивАтрибутов = Неопределено Тогда
        Сообщить("Массив префиксов не определен!");
    КонецЕсли;
    Для ИндексПрефикса = 0 По МассивАтрибутов.ВГраница() Цикл
        Если  (Найти(ЗаписьВСтроке, МассивАтрибутов[ИндексПрефикса])>0 и СравнитьПервыеСимволы(ЗаписьВСтроке, МассивАтрибутов[ИндексПрефикса])>0) Тогда
            ЗаписьЗначение = СтрЗаменить(ЗаписьВСтроке,МассивАтрибутов[ИндексПрефикса],"");
            ФорматированныйАтрибут = СтрЗаменить(СтрЗаменить(МассивАтрибутов[ИндексПрефикса],"=","")," ","")//отрезаем позможные пробелы и знак "="


            ВыходнойМассив.Добавить(ФорматированныйАтрибут);
            ВыходнойМассив.Добавить(ЗаписьЗначение);
            //ИндексПрефикса = ИндексПрефикса + 1;
            Сообщить("Функция ВыборАтрибутов. Выходое значение 0: "+ВыходнойМассив[0]);
            Сообщить("Функция ВыборАтрибутов. Выходое значение 1: "+ВыходнойМассив[1]);
            прервать;
        КонецЕсли;
    КонецЦикла;
Возврат ВыходнойМассив;// ну на всякий случай :))))

КонецФункции

запусти так
28 S3rGotcha
 
22.04.15
12:38
(27) Запустил уже.

В процедуре
Для а=0 по МассивСтроки.ВГраница() цикл
  Сообщить("Индекс: "+а+" Значение: "+МассивСтроки[а]);
  СТР=ВыборАтрибутов(МассивПрефиксов,МассивСтроки[а]);
  Сообщить("Процедура вывод1: "+СТР[0]);
  Сообщить("Процедура вывод2: "+СТР[1]);
КонецЦикла;

Вроде правильно отображает, но на последний элемент ругается: Индекс находится за границами массива. Т.е. первые 2 параметра со значениями выводятся. Последний - нет.
29 asady
 
22.04.15
12:45
Для а=0 по МассивСтроки.ВГраница() цикл
  Сообщить("Индекс: "+а+" Значение: "+МассивСтроки[а]);
  СТР=ВыборАтрибутов(МассивПрефиксов,МассивСтроки[а]);
  Если СТР.Количество()>0 Тогда
  Сообщить("Процедура вывод1: "+СТР[0]);
  Сообщить("Процедура вывод2: "+СТР[1]);
  Иначе
  Сообщить("массив пустой");
  конецесли;

КонецЦикла;
30 Jonny_Khomich
 
22.04.15
12:47
Массив = Новый Массив();
Возвтрат Массив;
31 Гёдза
 
22.04.15
12:53
Для а=0 по МассивСтроки.ВГраница() - 1цикл
32 S3rGotcha
 
22.04.15
13:56
(31) такая же ерунда. Не помогло.
33 asady
 
22.04.15
13:58
(32) у тебя выскакивает сообщение "массив пустой"?
ты отладчиком вообще пользоваться умеешь?
34 S3rGotcha
 
22.04.15
14:10
(33) нет, у меня выскакивает сообщение Индекс находится за границами массива. Все предыдущие элементы нормально отрабатываются функцией, а вот последний - никак.
35 asady
 
22.04.15
14:16
(34) какие сообщения у тебя выскакивают - скопируй сюда включая твои отладочные