Как правильно проапдейтить/инсертить табличку? Если в ней есть записи ?
---
обычно пишу так

```1c
    |UPDATE ...
    |IF @@ROWCOUNT = 0
    | INSERT ...
```

и не парюсь
---
Ёпрст, Есть несколько вариантов.
При наличии поля идентификатора, уникального для всех записей таблицы:
Обычно использовал:

```1c
    UPDATE ... table1 where ID = <ID>
    if @@rowcount = 0
    INS ERT IN TO table1 ...
```

но это работает для одной записи. Если вставить/обновить надо несколько записей, тогда лучше или их перебирать, или же сделать UPDATE и проверить @@rowcount чтобы был равным количеству обновляемых записей. Если @@rowcount меньше - тогда делать INSERT недостающих.
Если же уникального поля в таблице нет, тогда надо сравнивать все столбцы, и то не факт что не будет изменен дубль (если такой имеется в таблице).

p.s. Удивлен что вы спрашиваете такой вопрос :).
---
спасибо конечно, но всё это...на хрен не нужно.
:)
Вопрос вообще не в 1с и не за этим.
---
Ёпрст, А о какой таблице идет речь? Апдейт и Инсерт это как бы связано с SQL, или я чего то пропустил?
---
см (2-4)
---
Ёпрст, что-то спрашивающий про 7.7? Мир перевернулся...
---
тссс.. так надо
---
Ааа... Ну, тогда ждем счастливчика!
---
Я понимаю был бы вопрос на засыпку и для 1С 8: как правильно удалить строчки из таблицы значений.
---
kostyaomsk, и скорее всего, будете не правы. Потому что в 1с8 строки в таблице значений - удаляются по внутренним идентификаторам, а не по индексу. Можете проверить) Но для массива - будет справедливо - элементы из массива удаляются "снизу-вверх"
Зы. собственно это делает возможным определение ошибки что-то там "нельзя изменить строку таблицы значений, т.к. она была удалена". Строка таблицы значений "знает" о своем контейнере (метод Владелец()) - элемент массива же, в отличие от - о массиве ничего не "знает"
---
Allexe8.1, если коснуться вопроса именно удаления строк в ТаблицеЗначений 1С 8, то если действовать методом построчного перебора с анализом нужно идти снизу вверх. Для примера создал обработку с целью иллюстрации правильного и неправильного варианта удаления. Далее привожу фрагмент правильного и неправильного метода "перебора".
Правильный:

```1c
    // Исходные данные ТЗ - таблица значений в которой есть колонка "ФлагУдаления" тип булево.
    // Допустим, в таблице значений 5 строк
    МаксИнд = ТЗ.Количество()-1; // Вычисляем максимальный индекс строки (в нашем случае 4)
    Для Инд=0 По МаксИнд Цикл
    // Внутри цикла основной счетчик Инд будет последовательно принимать значения
    // от 0 До МаксИнд: 0, 1, 2, 3, 4.
    УбывающийСчетчикИндекс = МаксИнд - Инд; // Будет принимать значения: 4, 3, 2, 1, 0
    // Получаем очередную строку таблицы снизу вверх по вспомогательному убывающему индексу
    СтрТЗ = ТЗ[УбывающийСчетчикИндекс]; // Переменная СтрТЗ содержит ссылку на строку таблицы значений
    // Проверяем строку на условие удаления по условию ее колонки "ФлагУдаления"
    Если СтрТЗ.ФлагУдаления Тогда
    ТЗ.Удалить(УбывающийСчетчикИндекс); //
    // Теперь и в переменной СтрТЗ
    Сообщить ("Удалили строку с индексом "+Инд); //
    Иначе
    Сообщить ("Строка с индексом "+инд+" оставлена");
    КонецЕсли;
    КонецЦикла;
```

Неправильный (в лучшем случае не отработает корректно, в худшем ошибка периода исполнения при выходе индекса за границу диапазона при движении сверху вниз по таблице значений):

```1c
    МаксИнд = ТЗ.Количество()-1; // Вычисляем максимальный индекс строки (в нашем случае 4)
    Для Инд=0 По МаксИнд Цикл
    СтрТЗ = ТЗ[Инд];
    // Проверяем строку на условие удаления по условию ее колонки "ФлагУдаления"
    Если СтрТЗ.ФлагУдаления Тогда
    ТЗ.Удалить(Инд); //
    Сообщить ("Удалили строку с индексом "+Инд);
    Иначе
    Сообщить ("Строка с индексом "+инд+" оставлена");
    КонецЕсли;
    КонецЦикла;
```

Естественно, можно использовать более мощный метод ТЗ.НайтиСтроки(...), Поместить таблицу значений в запрос и прочее, но интерес представляет понятие "Внутренний идентификатор строки таблицы значений". Так полагаю ГУИД имеет смысл для тех данных что есть в базе (все что хранится в ее таблицах) + ГУИДы объектов метаданных конфигурации, еще ключ уникальности для форм, а вот для строк таблицы значений? Может быть как-то в ОЗУ при выполнении в среде 1С 8 есть какие-то служебные идентификаторы?
И еще один инетересный момент в 1с8 строки в таблице значений - удаляются по внутренним идентификаторам, а не по индексу. Это что означает. Наверное про непосредственное удаление средствами SQL?
А насчет утверждения собственно это делает возможным определение ошибки что-то там "нельзя изменить строку таблицы значений, т.к. она была удалена". Строка таблицы значений "знает" о своем контейнере (метод Владелец()) - элемент массива же, в отличие от - о массиве ничего не "знает"
тут действительно получается что при срабатывании метода таблицы значений
```1c
    ТЗ.Удалить(Индекс)
```
 переменная СтрТЗ где хранилась строка таблицы значений как-бы "помнит" структуру, но данных в ней уже нет.
Привожу обработку для тестирования удаления строк из таблицы значений и результаты работы отладчика при тестировании значений переменной строки таблицы значений и ее метода
```1c
    СтрТЗ.Владелец()
```
. В документации пишут что данный метод имеет практический смысл только для дерева значений. Какой смысл получается от него для таблицы значений?
---
kostyaomsk, если по индексу, то да, нужно снизу вверх, равно как и с массивом. При получении элементов по индексу - вы каждый раз получаете следующий элемент, при использовании "Для Каждого Из" - работаете со всей коллекцией. И в этом случае ошибки не будет.
....
Владелец()
Возвращаемое значение:
Тип: ТаблицаЗначений.
Описание:
Получает владельца данной строки.

По поводу внутр. идентификатора строки ТЗ - ошибся, вся информация о строках ТЗ - находится в самом объекте ТЗ.
Поэтому, например, "ЗначениеВСтрокуВнутр(ТЗ[0]) = ЗначениеВСтрокуВнутр(ТЗ[1])"
---
обычно пишу так

```1c
    |UPDATE ...
    |IF @@ROWCOUNT = 0
    | INSERT ...
```

и не парюсь
---
Верно, забыл про сериализацию таблицы значений. Но это уже к клиент-серверному взаимодействию относится. Если уж в тонком клиенте нельзя создать Объект ТаблицаЗначений на клиентской стороне из-за громоздкости, то передать его в виде текста в сериализованном виде можно. Один раз из практике хотели вывести ошибки при проведении документа, но не стали использовать этот вариант. Обычно имеет смысл тех объектов, которые уже есть в базе (документы) и, как правило, для обмена данными.
А раз уж начали эту тему в подробностях про ТаблицуЗначений добавлю код:

```1c
    А = ЗначениеВСтрокуВнутр(ТЗ[0]);
    Б = ЗначениеВСтрокуВнутр(ТЗ[1]);
    С = ЗначениеВСтрокуВнутр(ТЗ);
```

Из справки:
Глобальный контекст (Global context)
ЗначениеВСтрокуВнутр (ValueToStringInternal)
Синтаксис:
ЗначениеВСтрокуВнутр(<Значение>)
Параметры:
<Значение> (обязательный)
Тип: Произвольный.
Преобразуемое значение.
Возвращаемое значение:
Тип: Строка.
Системное представление значения в информационной базе.
Описание:
Получает системное строковое представление переданного значения.
В отладчике:
---
kostyaomsk, в общем забавно получается:
Попробовал следующим кодом пройтись в отладчике:

```1c
    ТЗ = Новый ТаблицаЗначений;
    ТЗ.Колонки.Добавить("Колонка");

    Стр1 = ТЗ.Добавить();
    Стр1.Колонка = 555;
    Стр2 = ТЗ.Добавить();
    Стр2.Колонка = 777;
    Стр3 = ТЗ.Добавить();
    Стр3.Колонка = 999;

    ВнутрСтрока1 = ЗначениеВСтрокуВнутр(ТЗ);
    ТЗ.Удалить(Стр2);
    ВнутрСтрока2 = ЗначениеВСтрокуВнутр(ТЗ);
```

Получилось, что, до удаления, т.е ВнутрСтрока1 =

```1c
    {"#",acf6192e-81ca-46ef-93a6-5a6968b78663,
    {8,
    {1,
    {0,"Колонка",
    {"Pattern"},",0}
    },
    {2,1,0,0,
    {1,3,
    {2,0,1,
    {"N",555},0},
    {2,1,1,
    {"N",777},0},
    {2,2,1,
    {"N",999},0}
    },0,2}
    }
    }
```

После удаления, ВнутрСтрока2 =

```1c
    {"#",acf6192e-81ca-46ef-93a6-5a6968b78663,
    {8,
    {1,
    {0,"Колонка",
    {"Pattern"},",0}
    },
    {2,1,0,0,
    {1,2,
    {2,0,1,
    {"N",555},0},
    {2,2,1,
    {"N",999},0}
    },0,2}
    }
    }
```

Обратите внимание на последовательность символов "{2,0,1,{"N",555},0}", "{2,2,1,{"N",999},0}"
Можно, предположить, что это и есть строка ТЗ. Причем видно, что "{2,1,1,{"N",777},0}" - после удаления исчезло из внутреннего представления. Скорее всего выделенные символ "{2,0,1", {2,1,1" и есть идентификаторы строк ТЗ. Собственно, поэтому при использования Для Каждого Из - индексы "не сбиваются" при удалении строк. Кстати, еще интересный вывод. Передавая, например, в функцию строку ТЗ, мы на самом деле передаем всю таблицу значений (точнее, указатель)
---
Извините конечно за флуд, но как тема удаления строк из таблиц 1с8 касается использования прямых запросов для обновления таблиц 1с7.7???
Мне вот лично было бы интересно почитать сообщения касающиеся темы, а найти их, с учетом ваших постов, очень сложно. Пожалуйста,создайте отдельную тему в соответствующей ветке, и там пишите.
---
а как обновить записи, я и сам кому хошь покажу..
---
Ёпрст, закрыл бы тему...