Будни автоматизации или "мне нужна программка для 3D упаковки"




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

99 Comments

  1. ildarovich

    Эта статья написана для публикации на сайте habrahabr.ru, поэтому запросы были переведены на английский.

    Reply
  2. AlX0id

    (1)

    И именно поэтому вот таким вот незамысловатым образом вы описываете 1с? ))

    Фреймворк, с которым мы работаем, основан на скриптовом языке. Хотя язык достаточно гибок и обвешен по принципу рождественской елки всякими хлопушками и погремушками, включая даже методы математической статистики, он не очень хорошо приспособлен для задач с объемными вычислениями. Обычный цикл у нас выполняется гораздо дольше, чем в компилируемом языке. Поэтому простые, но массовые вычисления бывает удобнее делать на стороне сервера непосредственно на уровне СУБД. Для работы с базой данных у нас используется язык, очень похожий на T-SQL.
    Reply
  3. Новенький_2209
    Причем наиболее глубокое впечатление почему-то осталось у тех, кого я подвозил тогда на своей синей импрезе. Все запомнили число 200, но это были отнюдь не достигнутые проценты утилизации объема короба. — Вот такой парадокс психологии!
    Кто водит из вас авто? Вспомните, как часто у вас такое наблюдается — сели в машину …вышли из машины. Вопрос — а что в дороге то хоть было? Вот реально — вы ее хоть помните? Угу, 10 раз. Вы едете на автопилоте. Ваш ум занят миллиардами мыслей, которые со скоростью света проносятся, поглощая вас еще сильнее. Какая дорога? «Не знаю такую!». А теперь задумайтесь, сколько времени вы находитесь в таком автопилоте? Метро, транспорт, …. на работе за монитором.

    откуда взято

    Reply
  4. kuntashov

    Хорошая статья! Должно взлететь )

    Reply
  5. yukon

    (2) AlX0id,

    И именно поэтому вот таким вот незамысловатым образом вы описываете 1с?

    Мне тоже понравилось. Описание просто шикарное.

    Reply
  6. CratosX

    про нуралиевку толсто

    Reply
  7. Evil Beaver

    Ildarovich опять творит невозможное запросами. А можно туповатым, вроде меня, объяснить что делают запросы, особенно тот, что с вращением?

    Reply
  8. ildarovich

    (6) Так Вы считаете эту шутку лучше убрать? (на хабре)

    Reply
  9. ildarovich

    (7) Эта задача интересна тем, что у нее есть минимум четыре различных решения:

    1) показанное здесь;

    2) варианты задаются сканируемой текстовой строкой типа «ДВШ ДШВ ВДШ ВШД ШДВ ШВД «;

    3) вращения вокруг каждой оси делаются внутри вложенных запросов;

    4) координаты образуются суммой К1 * Ш + К2 * В + К3 * Д, а коэффициенты берутся из искусственной таблицы.

    1) выбрано из-за того, что покороче в записи. А вообще, в задаче «container loading» еще учитывается возможность вращения коробки по осям (при укладке бывает важно не класть упаковку на бок, например), поэтому вариант 3) может быть предпочтительнее.

    Решение 1) основано на том, что на первом шаге таблица размеров «разворачивается» по измерениям. Каждой позиции таблицы размеров в таблице Scan соответствует три строчки: в первой ширина, во второй глубина, в третьей — высота.

    1 : 10 : 20 : 30

    ->

    1 : 10 : 1

    1 : 20 : 2

    1 : 30 : 3

    Потом таблица соединяется с собой два раза. Получается двадцать семь вариантов (ШШШ, ШШД, …, ВВВ) из которых убираются те, где минимум дважды повторяется одно измерение.

    1 : 10 : 10 : 10

    1 : 10 : 10 : 20

    1 : 10 : 10 : 30

    1 : 10 : 20 : 10

    1 : 10 : 20 : 20


    1 : 10 : 20 : 30

    1 : 20 : 10 : 10



    1 : 30 : 30 : 30

    Reply
  10. ildarovich

    Кстати, приведенный упаковочный лист очень хорошо показывает достоинства и недостатки использованного критерия. Видно, что шестая по порядку позиция Classic Jenga кладется выше, чем следующая за ней седьмая. Это от того, что шестая Jenga ложится на нижележащую упаковку без пустот, а под седьмой уже есть пустота, так как длина Jenga 28 см, а Фермера — 26 см. По той же причине Jenga кладется не плоско, а «ребром» — чтобы оставить под собой меньше пустоты.

    Иногда выгоднее использовать более простой критерий — учитывать только подъем уровня. Тогда формулы пересчета таблицы Vista упростятся. Наиболее сложное выражение в этом запросе связано как раз с расчетом образующейся под коробкой пустоты.

    И еще добавлю, что при выводе картинки размеры упаковок специально чуть сокращены внутрь их объема, так как иначе грани упаковок накладывались друг на друга и было вообще трудно что-либо разобрать. Поэтому расстояние, которое отделяет упаковки друг от друга на картинке не всегда есть в реальности.

    Reply
  11. soap

    Действительно описание роскошное.

    Reply
  12. DAnry

    Автор красиво излагает. Может пора переквалифицироваться в управдомы, извините в писатели…

    Reply
  13. CheBurator

    может не стоило изобретать велосиеппед а тупо использовать возможности, предоставляемые 3d-packer’om

    .

    http://www.packer3d.ru/

    Reply
  14. ildarovich

    (13) Это платный сервис. Оправдывает себя при загрузке контейнеров, вагонов, но не коробов. Рассматривалась и эта и другие возможности: есть еще один-два бесплатных сервиса, а также по крайней мере одна «standalone» программа для решения этой задачи. Но проблема их лицензирования и сопряжения с нашей конфигурацией намного сложнее чем подключение одной внешней печатной формы.

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

    Ну и «тупо использовать» что-либо — это вообще не наш метод, как вы, наверное, заметили.

    Reply
  15. Rustig

    сложный для понимания алгоритм 🙂

    Такой вопрос: если мы перевернем основную коробку на бок, получим ли мы то же решение, что и в первоначальном варианте? Если мы будем продолжать вращать основную коробку, будем ли мы получать то же решение, что и в первоначальном решении?

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

    Хотелось бы видеть в алгоритмах здравый смысл:

    1. по сумме объемов мелких коробок определяется минимальная основная коробка.

    2. располагать основную коробку на столе упаковки следует наибольшей по площади гранью.

    3. начинать упаковывание следует с более крупных коробок, которые могут быть расположены или на дне основной коробки или вдоль торца основной коробки

    4. в оставшиеся «прорези» по возможности упаковываем подходящие мелкие коробочки

    5. и т.д. с оставшейся свободной частью основной коробки — хотя понимаю, что реализация здравого смысла приведет как раз-таки к подобному сложному решению — перебору вариантов.

    Reply
  16. Rustig
  17. Evil Beaver

    Кстати, поскольку в общем виде задача является NP-полной, то какие ограничения имеют её существующие прикладные решения?

    Reply
  18. ildarovich

    (15) Сложным алгоритм является только на первый взгляд. Я просто не стал его «разжевывать», имея ввиду, что приложены запросы, по которым можно разобраться.

    На самом деле по сути это семейство алгоритмов. Общим является способ генерации ВСЕХ возможных вариантов укладки коробки (с учетом дискретизации) на каждом шаге и коррекции этих возможностей после ВЫБОРА одного варианта. Выбор варианта можно производить по разным критериям (эвристикам). Например, как показано в тексте конкретного запроса выбора сначала можно класть ту коробку, под которой будет оставаться минимум пустого пространства. А можно, изменив порядок сортировки (все остальное также) сначала класть наиболее объемную коробку или коробку наибольшей площади.

    С точки зрения программирования выбора алгоритм более чем прост — достаточно задать порядок сортировки в соответствующем запросе.

    Если повернуть основную коробку на бок — получим другое решение! Но так делать нежелательно, так как загружать коробку сбоку неудобно. Если окажется, что последнюю коробку потребуется поместить к верху задней стенки — в некоторых случаях это будет физически не возможно.

    Можете попробовать сформулировать свою эвристику 1-5 в виде порядка сортировки — должно получиться. Можно будет провести испытания. Если в среднем плотность упаковки с использованием вашей эвристики окажется больше, можно выбрать ее.

    Испытания приведенной эвристики показали на стандартных тестах (они опубликованы) результат 69-72%. Но у нас не было задачи увеличивать этот процент. Заказчики посчитали его достаточным. Тем более натурные эксперименты показали, что человек-упаковщик обеспечивает примерно такой-же процент.

    Судя по литературе, борьба за каждый процент свыше 77% многократно усложняет алгоритм.

    Reply
  19. ildarovich

    (16) Эти ссылки я не использовал точно. Первая хоть и относится к двумерному случаю, но очень интересна, но была просто позже, чем выполнялись работы. Вторая — никак не рассчитана на реализацию на 1С, поскольку использует алгоритм с возвратами к предыдущим шагам укладки — это просто долго на 1С.

    Я внимательно прочитал самые первые работы в данной области

    BISCHOFF, E. E., JANETZ, F. & RATCLIFF, M. S. W. /1995/. Loading pallets with non-identical items.

    European Journal of Operational Research, Vol. 84, pp. 681 — 692.

    BISCHOFF, E. E. & RATCLIFF, M. S. W. /1995/. Issues in the development of approaches to container

    loading. Omega, Vol. 23, pp. 377-390..

    Затем просмотрел более современные ссылки, чтобы определить, какие методы в общем позволяют улучшит результат и до скольких процентов. Выяснил, что улучшения небольшие.

    Также скачал стандартные тесты (могу найти ссылку).

    Также посмотрел истоки 3Д пакера. Кажется, это разработка команды из МГУ и теоретические основы их метода описаны в соответствующих работах. Там нет одной ясной идеи. Используется композиция приемов сведения задачи к двумерному случаю, если я правильно помню.

    Reply
  20. ildarovich

    (17) Не могу сейчас ответить на этот вопрос. Поскольку для этого нужно произвести отдельное исследование. Тем более, кажется, в последнее время появилось еще ряд решений.

    Но исходя из соображений «здравого смысла» все предлагаемые решения решают за приемлемое время (секунды) типичные практические задачи: загрузку кузова автомобиля, морского контейнера, вагона. Борьба идет не за проценты полезного использования объема контейнера (именно это касается математической сложности задачи и ее NP-полноты), а за другие вещи: удобство интерфейса, возможность ручных корректировок, наглядность представления получаемой упаковки, учет не прямоугольных упаковок, веса, совместимости грузов, устойчивости укладки и тому подобное.

    Предложенный метод ограничен тем, что работает с дискретным положением упаковок (укладка с точностью до сантиметра или НОД длин сторон упаковок). Время его работы прямо пропорционально произведению W x D x K x N, где W, D — размеры дна короба, K — число разноразмерных упаковок, N — число упаковок.

    Reply
  21. a-novoselov

    (0) Молодцы, красивое решение! Особенно после того, как несколько раз приходилось исправлять гениальные отчеты, в которых просроченная задолженность в циклах считается, очень приятно видеть такие решения запросами.

    (8) Насчет Хабра, думаю, вас все равно завалят вопросами «Что за скриптовый язык такой?», так что лучше сразу написать что в 1С это делалось. Но и уточнение, что встроенный язык это интерпретатор, не сильно предназначенный для объемных вычислений и тормозящий на больших циклах, тоже опускать не стоит.

    Reply
  22. Ёпрст

    (0)

    Это , а алгоритм рисования есть самого упаковочного листа ?

    Он должен быть не менее интересным.

    Reply
  23. Alex_IT

    (22) +1

    И инструмент рисования…

    Reply
  24. ildarovich

    (22) (23) Там все очень просто — это табличное поле 1С, используются его объекты-рисунки: линии и прямоугольники. Координаты, определяющие положение фигур считаются как проекции трехмерных координат на плоскость за коробкой. Это несложные формулы с элементами тригонометрии.

    В общем-то, если бы было нужно, можно было бы этими средствами и мультфильм, показывающий порядок упаковки, изобразить (своеобразный тетрис 3D).

    Но вот если вдруг понадобится удалять невидимые грани, будет непросто, так как нет объекта, который бы позволил залить цветом многоугольную область, чтобы воспользоваться методом z-буфера.

    Reply
  25. Ёпрст

    (24) мот, мини демо-пример?

    А то смутно представляю, как «палочки» рисовать в табличном поле, еще и разным цветом, еще и с циферкой в углу.

    Reply
  26. Ёпрст

    + не ясно, почему на рисунке между коробами «пустоты» .. они же лежат друг на друге, а не «висят» в воздухе ? Или это для облегчения «чтения» упаковочного листа ?

    Reply
  27. ildarovich

    (25) Вот весь код, который рисует блок

    Функция ДобавитьПрямую(Рисунки, x, y, dx, dy, Цвет, a = 0, b = 0, c = 0, d = 0)
    
    Результат = Рисунки.Добавить(ТипРисункаТабличногоДокумента.Прямая);
    ЗаполнитьЗначенияСвойств(Результат, Новый Структура(«Линия, Лево, Верх, Ширина, Высота, ЦветЛинии»
    , Новый Линия(ТипЛинииРисункаТабличногоДокумента.Точечная), Лево + x * Масштаб + a, Верх + y * Масштаб + b, dx * Масштаб + c, dy * Масштаб + d, Цвет));
    Возврат Результат
    
    КонецФункции
    
    Процедура НарисоватьБлок(Рисунки, x, y, z, dx, dy, dz, Текст, Цвет)
    
    Каркас = Новый Массив;
    
    x0 = x + z/2; y0 = y + z/2;
    
    //Каркас.Добавить(ДобавитьПрямую(Рисунки, x0,    y0,    dx,  0,  Цвет,  3, -1, -4,  0));
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0,    y0 — dy,   dx,  0,  Цвет,  3,  3, -4,  0));
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0 + dz/2,   y0 + dz/2,  dx,  0,  Цвет,  1, -3, -4,  0));
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0 + dz/2,   y0 + dz/2 — dy, dx,  0,  Цвет,  1,  1, -4,  0));
    
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0,    y0,    0,   -dy, Цвет,  3, -1,  0,  4));
    //Каркас.Добавить(ДобавитьПрямую(Рисунки, x0 + dx,   y0,    0,   -dy,  Цвет, -1, -1,  0,  4));
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0 + dz/2,   y0 + dz/2,   0,   -dy, Цвет,  1, -3,  0,  4));
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0 + dz/2 + dx, y0 + dz/2,   0,  -dy,  Цвет, -3, -3,  0,  4));
    
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0,    y0,    dz/2, dz/2, Цвет,  3, -1, -2, -2));
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0,    y0 — dy,   dz/2, dz/2,  Цвет,  3,  3, -2, -2));
    //Каркас.Добавить(ДобавитьПрямую(Рисунки, x0 + dx,   y0,    dz/2,  dz/2,  Цвет, -1, -1, -2, -2));
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0 + dx,   y0 — dy,   dz/2,  dz/2,  Цвет, -1,  3, -2, -2));
    
    ЗаполнитьЗначенияСвойств(Рисунки.Добавить(ТипРисункаТабличногоДокумента.Текст)
    , Новый Структура(«Лево, Верх, Авторазмер, Текст, ЦветТекста, ЦветЛинии»
    , Лево + (x0 + dz/2) * Масштаб + 1, Верх + (y0 + dz/2 — dy) * Масштаб + 1, Истина, Текст, Цвет, Цвет));
    
    КонецПроцедуры

    Показать

    Еще можете посмотреть как похожая задача решается при рисовании графа в статье Как нарисовать граф на 1С. Там можно скачать обработку и посмотреть, как происходит рисование, выбирается масштаб и прочее

    Reply
  28. ildarovich

    (26) Я уже говорил в комментарии (10), что

    при выводе картинки размеры упаковок специально чуть сокращены внутрь их объема, так как иначе грани упаковок накладывались друг на друга и было вообще трудно что-либо разобрать. Поэтому расстояние, которое отделяет упаковки друг от друга на картинке не всегда есть в реальности
    Reply
  29. Ёпрст

    Ага спасибо, еще пара уточняющих вопросов и мы из автора вытащим весь код целиком 🙂

    ЗЫ: на счет «пустот», это так и задумано ? Для простоты визуального восприятия ?

    Reply
  30. Ёпрст

    (28) Ага, я так и думал..

    Reply
  31. Ёпрст

    Жалко только, что алгоритм не всем подходит, нужно еще учитывать вес коробки и его «хрупкость», это если уж совсем «правильно» укладывать

    Reply
  32. ildarovich

    (29) Да пожалуйста. На самом деле я собирался привести и обработку целиком, но для Хабра она не интересна, да и к статье ее сейчас приложить нельзя, поэтому чуть сэкономил время. Поскольку для публикации обработки еще нужно привести способ хранения габаритов упаковок, так как в штатной УТ10 его нет, а в УТ11 есть габариты, но тара не так определяется. В общем, пока решил с этим не спешить.

    Reply
  33. ildarovich

    (31) И вес коробки и хрупкость можно учесть — все регулируется порядком сортировки в соответствующем запросе, куда можно добавить указанные поля.

    Reply
  34. Ёпрст

    Круто, если демку оформите, хотя бы с одним справочником и одним документом.

    Reply
  35. Дмитрий74Чел

    (1) Я уж хотел написать «и что эта статья с Хабра делает на Инфостарте»? 🙂

    Reply
  36. Evil Beaver

    (32) кстати, когда ждать статью на хабре?

    Reply
  37. ildarovich

    (36) Вообще-то статья уже вышла. Это было 28.03.14. Вот ссылка.

    Reply
  38. Evil Beaver

    (37) извиняюсь, не заметил ее там.

    Reply
  39. FractonKireyev

    Чем была нарисована картинка со схемой укладки в коробку?

    Reply
  40. FractonKireyev

    По поводу хрупкости (для (31) и (33)).

    Всё совсем не так просто. Если товар лежит так (считаем, что твёрдые коробки не ниже хрупкой):

    твёрдый — хрупкий — твёрдый

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

    Так что просто сортировкой в запросе просто так не отделаться — нужны какие-то другие алгоритмы.

    Reply
  41. ildarovich

    (39) FractonKireyev, в комментарии (27) я уже отвечал на этот вопрос. Это чистый 1С, используется поле табличного документа и объект «рисунок» типа линия. В том же комментарии приведен ВЕСЬ необходимый код рисования блока.

    (40) Вариантов алгоритмов великое множество. Тот вариант, о котором говорите Вы (твердые должны опираться на твердые), можно считать подмножеством приведенного, если в нем ввести сортировку по критерию минимизации опоры на хрупкие коробки.

    Reply
  42. Alex_IT

    (32) Интересно увидеть обработку, в любом виде, даже без возможности использования в типовых. Само рисование в 1С ну очень куцее и любое удачное визуальное решение всегда вызывает интерес.

    Reply
  43. ildarovich

    (42) Alex_IT, обработку я со временем выложу, приспособив ее и к 10.3 и к 11 (уже почти все готово). Но если Вас интересует только рисование, обратите внимание на мой комментарий (23). Там приведен ВЕСЬ код из обработки, необходимый для рисования блоков в 2,5 D.

    Reply
  44. CheBurator

    Вообще, конечно автор молодец!

    еще в запросы впихнуть ограничения по каждой коробке (типа нельзя ставит на торец или типа как хрупкое с опорой выше)… и демо конфу минимальную… передавать в «пакете» исходные коробки на выходе получать раскладки…

    Reply
  45. CheBurator

    вообще не сильно понятно наскольо эффективно работает такая упаковка ФИЗИЧЕСКи — ладноя понимаю палеты/конейтнеры комплектовать, но коробки размером 60см на 80… на 40… если упаковке подлежит большое колво разноообразного товара то имхо упаковщики которые стоят на упаковке сделают близко к оптимальному и без раскладки…

    .

    окупается ди сам процесс УПАКОВКИ КОРОБОК ПО СХЕМЕ?

    Reply
  46. ildarovich

    (49) CheBurator,

    упаковщики которые стоят на упаковке сделают близко к оптимальному и без раскладки…

    Сам так думал, но недавно, после того, как вспомнили про задачу в связи со статьей, мы провели эксперимент: двух стажеров попросили заполнить короб разными найденными в офисе коробочками. Удивительно, но стажеры во всех попытках справились с работой хуже программки. Правда, мои коллеги отнесли все на способности стажеров, но все же факт остается фактом.

    А про окупаемость можно рассудить так: если нужны упаковочные листы, то можно

    1) получить их заранее и разложить товар по коробкам в соответствии с ними, подглядывая в упаковочный лист;

    2) получить упаковочный лист после укладки, просканировав товар.

    Кажется, первый вариант, не требующий сканера и лишнего хождения к принтеру, выглядит экономичнее.

    Если упаковочные листы не нужны, то смысла тратить явно большее время на укладку по просчитанной схеме нет. Лучше натренировать упаковщика.

    Reply
  47. Kopman

    Хорошая статья. Присоединяюсь к желающим увидеть обработку.

    Reply
  48. alexandr851c

    Хотелось бы увидеть обработку. Будет ли она выложена?

    Reply
  49. ildarovich

    (52) alexandr851c, обработка будет выложена. Когда — пока сказать не могу.

    Reply
  50. alexandr851c

    (53) а можете кинуть саму процедуру упаковки ))) Заранее огромное спасибо.

    Reply
  51. scientes

    Что интересно, похоже в приведенном коде есть опечатка. Взялся проверять самый первый запрос.

    SELECT 0 AS x
    INTO R1
    UNION
    SELECT 1;
    
    SELECT L.x + 2 * H.x AS x
    INTO R2
    FROM R1 AS L, R1 AS H;
    
    SELECT L.x + 2 * H.x AS x
    INTO R4
    FROM R2 AS L, R2 AS H;
    
    SELECT L.x + 2 * H.x AS x
    INTO R8
    FROM R4 AS L, R4 AS H;

    Показать

    Чтобы получилась последовательность от 0 до 255, надо в таблице R4 использовать коэффициент 4, а в таблице R8 коэффициент 16.

    Reply
  52. ildarovich

    (55) scientes, вы очень внимательны. Ошибку исправлю. Она появилась в ходе перевода запроса на английский. Сам принцип такого способа генерации множества чисел изложен в статье «Порождающий запрос».

    Reply
  53. Salavat

    эх,.. что то с наименованиями полей напутано. начиная с

    INTO Vista

    похоже.

    но конкретно — в

    SELECT TOP 1 id, d0l, d1l, d2l, d0h, d1h, d2
    FR OM Vista
    WHERE d2l + d2 < = &Height
    ORDER BY s * d2l — v, s * d2 DESC, d2l + d2, d0l, d1l, d0h;

    у Vista нет (из предыдущего запроса) — d2.

    я правильно понял — там d2h нужно?

    а в следующем запросе — там (или ранее где) перепутано (кроме указанного) с it — он такой же как и в

    SELECT id, CASE x WHEN 0 THEN d0 WHEN 1 THEN d1 WHEN 2 THEN d2 END AS dx, x
    INTO Scan
    FR OM Items, R2
    WH ERE x < 3;

    ?

    если да, то в последнем уже снова для него появились —

    It.d2l, It.d1l,

    , и аналогичные…

    Автор, прокомментируйте пожалуйста.

    Reply
  54. CheBurator

    мне бы данная обработка пригодилась бы для расчета «сколько однотипных коробок влезитя в ячейку заданного размера».

    Reply
  55. ildarovich

    (58) CheBurator, конечно, данный подход решит эту задачу, но для нее есть гораздо более простые способы. Что мешает поделить длину ячейки на длину одной упаковки, ширину ячейки на ширину упаковки, высоту ячейки на высоту упаковки, затем взять целые части результатов деления и перемножить их? Или упаковки можно по-разному вращать при складывании?

    Reply
  56. CheBurator

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

    http://screencast.com/t/6HLjQIxZl0p (вид на палету сверху) — 7 коробок в слое, следующий слой кладется наоборот : 2 коробки получатся слева…

    как например посчитать такую раскладку слоя сходу — навскидку не соображу. Здесь что «хорошо» — все коробки одного размера.

    .

    при такой раскладке высота всех коробок одинаковая.

    а вот например при запихивании в ячейку активного хранения можно извращаться и посильнее — какие-то коробки на торец ставить и т.д. — будет ли при этом выигрыш — хз…

    Reply
  57. ildarovich
    Reply
  58. Salavat

    (61) а что за переменные &Высота, Ширина, Глубина — это размеры Номенклатуры или Ящика?

    Reply
  59. ildarovich

    (62) Salavat, это размеры ящика (короба)

    Reply
  60. Salavat

    (61)

    …
    Зона.ИндексКоробки,
    Зона.Лево КАК Лево,
    Зона.Тыл КАК Тыл,
    Зона.Низ,
    Зона.Право КАК Право,
    Зона.Фронт,
    Зона.Высота КАК Высота,
    …
    Зона.Опора,
    Зона.Площадь,
    …

    Показать

    Коробки как я понял — это всё-таки Номенклатура?

    А зачем так много полей и/или — что они значат? Лево, Право,.. Тыл, Фронт,.. Опора, Площадь,..

    Из перечисленного только понял про Низ и Высота — разве не достаточно было всё так и обозначать через координаты начального угла и размеры граней номенклатуры?

    Reply
  61. ildarovich

    (64) Salavat, в принципе, положение коробки, которую можно вращать, задается шестью параметрами. Ими действительно могут быть координаты угла (три числа) и размеры сторон (три числа). А могут быть и координаты граней (Лево, Право, Тыл, Фронт, Низ, Верх). Или комбинированный вариант, как у меня: Лево, Право, Тыл, Фронт, Низ, Высота. Я выбрал такой вариант, чтобы минимизировать вычисления при определении пересечений. Для определения пересечения нужно знать, например правый край. И его не нужно вычислять как Лево + Ширина. Он хранится как «Право». В отношении Низа и Верха получилось, что Высота в расчетах используется чаще чем Верх и я взял высоту.

    В общем, это все для минимизации вычислений в процессе работы.

    Также про «опору» и площадь. Площадь считается сразу — она у варианта не меняется. Это произведение ширины на глубину (мы стоим перед коробкой). «Опора» — это более сложная вещь. Это сколько занятого объема находится под дном номенклатуры. В идеале под номенклатурой не должно быть пустоты — «опора» должна быть равна произведению площади на координату «низ» коробки. Разница говорит о пустоте. Чем она больше, тем больше пустоты под коробкой. Поэтому разница объема под коробкой и «опоры» используется для сортировки вариантов по критерию минимума незанятого пространства.

    Reply
  62. Salavat

    (65) ок — ладно с координатами вроде (!) понятно.

    но чем дальше я пытаюсь разобраться, тем больше мне всё это напоминает миф какойто красиво нарисованный (+/-).

    далее — таблицы?

    Зона — это как уложено на данной итерации?

    Укладка — это что такое?

    Вобще — мне малоинтересна теория, т.б. тянущая не менее чем на курсовик.

    Достаточно (и полезнее) былобы на уровне — »



    1. Запрос …….. — .

    2. &А, &Б, &В — размеры, которые подставить в виде…

    3. Таблица БлаБлаБла — ……. которая ……. и …

    …»

    мне бы (да и другим — не сомневаюсь) — гораздо полезнее была бы публикация, которую можно было использовать Практически, а не для убийства времени, разгадывания — что/куда/откуда/как/когда/… …

    Спасибо если поняли о чём я прошу.

    Reply
  63. Salavat
    Reply
  64. ildarovich
    Reply
  65. Salavat
    Reply
  66. ildarovich

    (69) Salavat, миллиметры нужно отсечь. Обязательно.

    Зона — это таблица.

    1) в ней нужно выбрать одну строку. Запрос для выбора приведен в функции ВыборМеста. Смысл его в том, чтобы выбрать лучший вариант размещения коробки. В этой строке уже решение для одной коробки — можете его вывести как либо. Там есть номер коробки, ее положение и все ее размеры. Теперь уменьшаем на один число таких коробок к размещению.

    2) Если число коробок такого типоразмера (с таким Id) стало равно нулю, все такие коробки нужно удалить из таблицы Зона — переписать ее с условием ГДЕ Id <> IdВыбраннойКоробки.

    У меня Id коробки соответствовал строке табличной части ЗаказаПокупателя. То есть, если оказывалось, что в строке уже не оставалось не размещенных позиций, то Id удалялось из таблицы Зона.

    3) Если выбранная коробка мешает возможным вариантам, то их нужно скорректировать. Как это делается — делается запрос к таблице Зона. В запросе указываются параметры. Запрос возвращает новую таблицу Зона. Уже пересчитанную. В ней все варианты скорректированы. Некоторые оставлены без изменения (на которые не повлияло сделанное размещение), а у некоторых изменен «Низ», также пересчитана «опора».

    Такая же таблица по структуре получается, но с некоторыми другими числами, относительно уровня, где теперь могут помещаться коробки.

    У меня 2) и 3) делаются в одном запросе «УкладкаКоробки».

    Пункт 1) повторяется, пока возможен выбор, пока запрос ВыборМеста возвращает строку. Там ограничена высота и если не найдется вариантов, высота верха коробки в котором будет меньше, чем высота ящика, то запрос ничего не вернет.

    Тогда увеличивается число использованных ящиков и повторяется инициализация (приземление). Варианты опять рассматриваются, начиная с дна ящика.

    То есть решение получается в виде последовательности строк, выбираемых из таблицы «Зона». Каждая выбранная за один раз строка — это укладка одной коробки. После каждой укладки вся таблица «Зона» пересчитывается. Или инициализируется заново при взятии нового ящика.

    Reply
  67. Salavat
    Reply
  68. ildarovich

    (71) Salavat, нет, весь результат — это таблица «Укладка».

    К ней по одной на каждом шаге добавляются строки, выбираемые из таблицы «Зона».

    Кстати, и номер короба (ящика) туда пишется.

    «Зона» — это рабочая таблица ВСЕХ вариантов, а «Укладка» — это полученное размещение.

    Именно поэтому в процедуре «Укладка» из таблицы Укладка выбирается одна последняя строка. Она была только что добавлена при выборе места. И эта строка используется для корректировки рабочей таблицы «Зана». В итоге в таблице «Укладка» столько строк, сколько было всего в сумме коробок (упаковок) в заказе. А в таблице «Зона» число строк — это число вариантов положить одну из оставшихся коробок на очередном шаге.

    Вообще куда складывать результат и прочее — это не столь существенные технические подробности. Они с алгоритмом не так уж сильно связаны. Это я к тому, что в других версиях обработки можно сделать (и сделано) по-другому.

    Кстати, думал, что в отправленном мною тексте это было, а оказывается — нет. Вот основной цикл:

    НомерКороба = 0;
    Укладка.Очистить();
    Инициализация();
    Пока Приземление() Цикл
    НомерКороба = НомерКороба + 1;
    Пока ВыборМеста() Цикл
    УкладкаКоробки()
    КонецЦикла
    КонецЦикла
    

    Показать

    Reply
  69. Salavat

    (72) «Вообще куда складывать результат и прочее — это не столь существенные технические подробности.» — разве?

    А если у нас расчитанное положение позиции на дне (допустим) только, а мы (не зная это) заложили его место другими?

    При этом — позиции у нас не очень лёгкие.

    Или я снова не понял.

    Reply
  70. ildarovich

    (73) Salavat, про технические подробности я имел ввиду не подробности алгоритма укладки, а подробности реализации в виде обработки. Дело в том, что функции и структуры данных выдернуты из обработки, используемой для отладки. Где данные загружаются и выгружаются в запрос лишние разы, чтобы видеть, что происходит. Отвечая на вопрос: какая таблица для чего, я уже говорю не про алгоритм, а про подробности реализации, которая может быть и другой при сохранении основной идеи, но я отвлекся…

    Давайте еще раз другими словами о том, в чем суть алгоритма:

    Коробки укладываются по одной, начиная с дна ящика. Так, как их укладывает человек. Мы не можем выбрать место для очередной коробки, чтобы она висела в воздухе — она должна опираться на дно или другие коробки. Для каждого шага имеется таблица вариантов «Vista» (как в статье). Каждая запись-вариант в таблице хранит номер коробки, положение ее левого и правого, ближнего и дальнего края, низа и высоты. В самый первый момент коробки «приземлены» — во всех вариантах низ = 0 и коробки находятся на дне ящика. Также нулю равна пустота (незанятое место под коробками).

    Далее выбираем один вариант. Значит, одна коробка зафиксирована на дне ящика. Теперь все варианты из таблицы, которые должны были занять то же место (или часть того же места) должны быть скорректированы, поскольку непосредственно на дно в этом месте положить другую коробку уже нельзя. Но другую коробку можно положить на верх уже положенной коробки. Поэтому у того варианта, который пересекается с уже положенной (положенная — это последняя строка в таблице укладка), должен быть увеличен «низ». Он должен стать равен верху уже положенной коробки.

    То есть выбираем один конкретный вариант положить коробку, дописываем его к таблице «Укладка». И просматриваем все записи в таблице вариантов Зона. Те записи, которые стали неактуальны (невозможны физически), меняем, поднимая выше значение поля «низ». То есть постепенно низ всех коробок в таблице вариантов будет выше и выше, пока не превысит высоту ящика. Тогда мы возьмем новый ящик, «приземлим» оставшиеся варианты и так далее.

    Reply
  71. Salavat

    (72) за

    НомерКороба = 0;

    Укладка.Очистить();

    Инициализация();

    Пока Приземление() Цикл

    НомерКороба = НомерКороба + 1;

    Пока ВыборМеста() Цикл

    УкладкаКоробки()

    КонецЦикла

    КонецЦикла

    — Спасибо! удалось наконецто увидеть всю (надеюсь) тему.

    удалось запустить, но (как я примерно и говорил изначально) — проблема с количествами!

    нет проверки на количество в списке Номенклатуры. Точнее — оно есть, но такое, что я не понял как заставить его работать.

    В итоге получил — бесконечный цикл — количество Номенклатуры уменьшается до бесконечности. Причём количество — только у последней строки номенклатуры — нет перехода по строкам Номенклатуры.

    Файл прикладываю — УТ 10.3. В справочник Номенклатура добавлены реквизиты — Высота, Ширина, Глубина.

    Помогите, пожалуйста.

    Reply
  72. Salavat

    (74) эта строка (теперь)

    ИндексКоробки = ?(Коробки[Строка.ИндексКоробки — 1].Количество = 0, Строка.ИндексКоробки, 0);

    — меня озадачивает. что за

    ИндексКоробки =

    ? оно ведь нигде не используется.

    Почему оно — или Строка.ИндексКоробки, или 0 ?

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

    … Коробки[Строка.ИндексКоробки — 1]…

    но, это я только подозреваю, как/что/куда/откуда/… — я снова не вижу.

    Reply
  73. Salavat

    ildarovich, ну так что — что с количеством делать? как/когда/где/… его правильно учесть?

    Reply
  74. Salavat

    и попутно — опять ведь перемешано — (27)

    Функция ДобавитьПрямую(Рисунки, x, y, dx, dy, Цвет, a = 0, b = 0, c = 0, d = 0)
    
    Результат = Рисунки.Добавить(ТипРисункаТабличногоДокумента.Прямая);
    ЗаполнитьЗначенияСвойств(Результат, Новый Структура(«Линия, Лево, Верх, Ширина, Высота, ЦветЛинии»
    , Новый Линия(ТипЛинииРисункаТабличногоДокумента.Точечная), Лево + x * Масштаб + a, Верх + y * Масштаб + b, dx * Масштаб + c, dy * Масштаб + d, Цвет));
    Возврат Результат
    
    КонецФункции
    
    Процедура НарисоватьБлок(Рисунки, x, y, z, dx, dy, dz, Текст, Цвет)
    
    Каркас = Новый Массив;
    
    x0 = x + z/2; y0 = y + z/2;
    
    //Каркас.Добавить(ДобавитьПрямую(Рисунки, x0,             y0,                dx,     0,        Цвет,  3, -1, -4,  0));
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0,             y0 — dy,         dx,     0,        Цвет,  3,  3, -4,  0));
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0 + dz/2,         y0 + dz/2,        dx,     0,        Цвет,  1, -3, -4,  0));
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0 + dz/2,         y0 + dz/2 — dy,    dx,     0,        Цвет,  1,  1, -4,  0));
    
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0,             y0,             0,         -dy,    Цвет,  3, -1,  0,  4));
    //Каркас.Добавить(ДобавитьПрямую(Рисунки, x0 + dx,         y0,                0,         -dy,     Цвет, -1, -1,  0,  4));
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0 + dz/2,         y0 + dz/2,         0,         -dy,    Цвет,  1, -3,  0,  4));
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0 + dz/2 + dx,    y0 + dz/2,         0,        -dy,     Цвет, -3, -3,  0,  4));
    
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0,                y0,             dz/2,    dz/2,    Цвет,  3, -1, -2, -2));
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0,                y0 — dy,         dz/2,    dz/2,     Цвет,  3,  3, -2, -2));
    //Каркас.Добавить(ДобавитьПрямую(Рисунки, x0 + dx,         y0,             dz/2,     dz/2,     Цвет, -1, -1, -2, -2));
    Каркас.Добавить(ДобавитьПрямую(Рисунки, x0 + dx,         y0 — dy,         dz/2,     dz/2,     Цвет, -1,  3, -2, -2));
    
    ЗаполнитьЗначенияСвойств(Рисунки.Добавить(ТипРисункаТабличногоДокумента.Текст)
    , Новый Структура(«Лево, Верх, Авторазмер, Текст, ЦветТекста, ЦветЛинии»
    , Лево + (x0 + dz/2) * Масштаб + 1, Верх + (y0 + dz/2 — dy) * Масштаб + 1, Истина, Текст, Цвет, Цвет));
    
    КонецПроцедуры

    Показать

    и по-русски и по английски…

    dz — это Высота или что? dy — ширина или право? dx — Тыл или (Фронт минус Тыл) или наоборот или как?

    Масштаб ладно — подбором ещё можно угадать, что там подставлять.

    ДобавитьПрямую() — что за a, b, c,………?

    и т.д………….

    Reply
  75. Salavat

    (78) Salavat, Вобщем с рисованием разобрался (рисование написал по-своему) — вопрос отменяется.

    Попутно выяснилось, что в Укладке нет Номера Ящика — добавил и его.

    С перебором Номенклатуры (и с её количеством) — вопрос открытый.

    Reply
  76. Salavat

    Вобщем нашёл и проблема (в количествах) где кроится……….

    А в таблице «Зона» число строк — это число вариантов положить одну из оставшихся коробок на очередном шаге.

    (72) ildarovich — здесь не оставшиеся, а те, что были получены в самом начале.

    но и это — только часть проблемы (подозреваю).

    Автор, сделайте пожалуйста рабочий вариант или скажите (предметно) — как решить проблему.

    ведь — нерабочий вариант же.

    Reply
  77. Salavat

    непонятно зачем нужны в Зоне колонки Опора и Низ — они же нулевые.

    Reply
  78. ildarovich

    (80) Salavat, нужно было всего лишь реквизит «ИндексКоробки» (числового типа) добавить к реквизитам обработки. Тогда ИндексКоробки будет передаваться в запрос «Укладка» и при достижении нулевого количества такой номенклатуры она будет удаляться из таблицы Зона по условию. Об этом был пункт 2) в комментарии (70).

    Reply
  79. ildarovich

    (81) Salavat, про это я уже писал, перечитайте внимательнее. Теперь, когда Ваша обработка уже должна работать, сможете посмотреть как меняются данные в этих колонках по мере укладки коробок в ящик.

    Reply
  80. Salavat

    (82) пробовал — не вышло, в итоге добавил — в другое место. и — ……… короче через зад.

    (83) никак они (эти колонки) в таблице Зона не меняются. в Укладке — да, они (эти колонки) разные.

    Вобщем — вроде работает, но, как/что/правильноли/………….. — я точно не скажу сейчас. потому что — я уже описал что (неединственное).

    Хотел поблагодарить (изначально), но честно — нет никакого желания (сейчас).

    Вопрос задаю — получаю кучу слов, которые я не могу (за редким исключением, которое надо ещё найти/выудить из этой кучи) использовать, реально.

    я же не за чтением романа сюда пришёл — зачем краснословии упражняться.

    Почему? Потому что если я выкладываю, то стараюсь выложить понятное и/или рабочее. Если оцениваю это денежно, то — за деньги.

    Иначе же — ничего не выкладываю, а просто пишу — я сделал офигенную вещь похвалите меня!

    сами выберите — к какой стороне отнести себя.

    Reply
  81. ildarovich

    (84) Salavat, я совершенно точно не хотел ничего пока выкладывать (в этой конкретной статье), то есть реализовал вариант:

    ничего не выкладываю, а просто пишу — я сделал офигенную вещь — похвалите меня!

    Это Вам что-то понадобилось и Вы стали меня просить. В итоге я Вам «за пожалуйста» постепенно с объяснениями переслал всю начинку своей обработки, которую использовал для отладки. При этом мне показалось, что Вам не очень хотелось разбираться, а хотелось получить готовый результат и таким образом Вы своей цели добились.- Удачи!

    Reply
  82. Salavat

    (85) не совсем так.

    я увидел публикацию, расценил её как нечто полезное, но ……… и в ней, и в присланном изложено так, что … — вобщем это нерабочее, а именно — согласились вобщем Вы.

    мне только непонятно — Вы читаете литературу (я не имею ввиду — левые видеоуроки, например) и там тоже разбираетесь?

    Я нет — я привык взять и прочитать. Прочитать столько, сколько понадобится, но чтоб читаемое было понятным, а не водой/соломой/…. разбавлено.

    Цель моя (и здесь, и обычно) — решить. Решить, это значит — должно работать и я знаю как.

    Сейчас же — я не уверен, что работает и не знаю как.

    Зато в краснословии Вы себе не отказываете — Удачи!!

    Reply
  83. ildarovich

    (86) Salavat, спасибо, приму к сведению

    Reply
  84. CheBurator

    …дайте уже обработку для 8-ки, потестить…. чтобы на вход задать можно было габариты «ящика-получателя» (дл, шир, выс) и размер коробки (дл, шир, выс), а на выходе — сколько коробок влезет в ящик — есть такое?

    спсб!

    Reply
  85. ildarovich

    (88) CheBurator, сделаю это в ближайшие дни.

    Reply
  86. Salavat

    (83) вобщем как я и подозревал — работает неверно.

    рисует красиво, но цифры левые.

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

    при чём — логику проследить, у меня абслютно не вышло.

    однозначно — результатт неверный.

    Автор, разъясните пожалуйста.

    Reply
  87. Salavat

    Единственное, что я заметил беспроблемное, это количество номенклатуры — оно верно (сейчас).

    но, это очень трудно назвать решением данной задачи.

    Reply
  88. Salavat

    попытался разобраться в получаемой якобы-укладке — для 3 пробных позиций (по 10 штук):

    1. высота:

    у первой — получаеттся разная — от первой и второй позиции,

    у второй — от первой,

    у третьей — от второй и от той, которой нет вообще…

    2. ширина:

    у первой — от первой и третьей,

    у второй — от первой,

    у третьей — от третьей и несуществующей.

    3. глубина:

    у первой — от первой и несуществующей,

    у второй — от несуществующей,

    у третьей — от второй и третьей.

    это всё, что я насмотрел.

    подозреваю косяк(и) в запросах/переборе/…

    но это — только моё подозрение.

    Автор, прокомментируйте, пожалуйста.

    Reply
  89. ildarovich

    (92) Salavat, пришлите, пожалуйста, мне на почту текущий вариант отлаживаемой обработки — я его посмотрю.

    Reply
  90. ildarovich

    (93) Я уже переписал и исправил обработку, составленную без особенного понимания исключительно из моих ответов, был готов ее отправить. В личной переписке корреспондент был предупрежден, что одним из условий было ее использование для апробации, для одного конкретного клиента и нераспространение. Она лежала в папке «Исходящие».

    Но тут мне прислали интересную ссылку ….

    Оказалось, что еще не работающая обработка, построенная из моих запросов и бесплатных советов с 1-го октября уже продается на сайте … под авторством Салавата за целых 15 000 рублей!. (сейчас он уже обещал ее убрать)

    -Так что держите ухо востро!

    Reply
  91. headMade

    (94)

    хуже умных врагов — только хитрожопые друзья )))

    Reply
  92. Salavat

    (94) сразу обозначу свою т.з. — еслиб меня не заинтересовала тема, я бы не задавал столько вопросов.

    по ответу — автор похоже с головой своей не совсем дружит. по-крайней мере — в этот момент.

    1. Любой человек, видя объём вопросов (непустых и от одного человека) прекрасно поймёт, что тема заинтересовала. И не по тому, что запор долгий в туалете.

    2.

    …личной переписке корреспондент был предупрежден, что одним из условий было ее использование для апробации, для одного конкретного клиента и нераспространение

    — гляньте в переписку, освежите память свою сначала. Более того — в той же переписке предлагалась цена (да, не золотые горы и он вроде обещал подумать/торговаться, но … видя его обещания здешние, с апреля — я засомневался уже).

    И последнее (надеюсь) — Вы хоть ради общего обзора — гляньте ст. 138, 137,..(остальное, из той же главы — тоже не помешает) УК РФ. Конкретно — я про переписку имею ввиду.

    и — не говорите, что я вдруг угрожаю (малоли…). Я опять же — прошу только.

    Надеюсь хотя бы про последнее (малоли…) не скажете, что я снова присваиваю чужое авторство.

    Reply
  93. ildarovich

    (96) Salavat, а не Вы ли пытались продать мою обработку за 15 000 рублей под видом своей на сайте …? А не Вас ли поймали за руку на конкретном плагиате «на горячем»? А не лучше ли сейчас покраснеть и публично извиниться?

    Reply
  94. Salavat

    (97)

    1. я нашёл тему.

    2. задавал вопросы автору и предлагал ему оплату.

    3. сделал (как думал — правильно) разместил.

    4. я ни где не писал про своё авторство, продавать и говорить об авторстве — это разные вещи, если Вы не в курсе.

    и — я тоже могу Вас обвинить в плагиате — немоего, разумеется, но пардон — в теме также не вижу упоминаний про то, откуда/какие/методы взяты. Былиб я б элементарно прошёлся по ним сначала, т.к. здесь — не всё есть.

    где я не прав/вру/… — за что я должен извиниться?

    я могу также сказать — что это Вы мою обработку себе приписываете? (см. 4…)

    может хватит бахвальства излишнего? я почемуто подумал, что по т/ф мы договорились уже.

    Reply
  95. Salavat

    (97) чувствую Вы снова разницу не знаете, разъясняю:

    «моё» — это можно сказать когда Вы мне дали (я украл — б.р.) и я её (1к1 ну или минимум изменений) продаю.

    я (не отрицал этого никогда, но меня об этом и не спрашивал никто, спросили/попросилиб я бы сказал/написал) — получил от Вас тексты, пытался их собрать безуспешно (ну да — с помощью Вашей всё же получилось, почти).

    но пардон — я тоже руку приложил к этому, немалую.

    в итоге:

    — я Вам предлагал деньги изначально,

    — я немало сам накопал в сделанном.

    — условий, о которых Вы предупреждали якобы, повторю — не было такого.

    Вы уж разберитесь с собой — кто не прав.

    я предложил ведь — чаю попить, успокоиться сначала.

    Reply
  96. ildarovich

    (98) Salavat,

    1. я нашёл тему.

    — на первой странице Инфостарт

    2. задавал вопросы автору и предлагал ему оплату.

    Очень-очень-очень много вопросов, предложив для начала за готовую обработку(а мне и не нужно) 1,5(!!!) тысячи российских рублей

    3. сделал (как думал — правильно) разместил.

    — сложил вместе все присланные ФУНКЦИИ, даже не запросы — я замучился объяснять куда их вставлять и прислал все ключевые функции, а рисование еще раньше в одном из комментариев показал. То есть где это сделанное? В той выложенной (Вашей ее назвать нельзя) обработке практически нет никакого, кроме моего, кода, да еще В МОДУЛЕ ФОРМЫ, а не там, где полагается.

    4. продавать и говорить об авторстве — это разные вещи

    то есть можно продавать чужое, не уведомляя автора и не спрашивая его разрешения? — И много такого Вы уже напродавали? — Может быть, всем теперь нужно свои карманы проверить? По поводу того, что этот метод мной у кого-то заимствован — бред сивой кобылы — метод я придумал с «0», прочитав несколько статей на английском языке в зарубежных журналах (список первоисточников я приводил в одном из комментариев). Впрочем, проводить себе во вред тут ликбез по авторскому праву я не буду.

    Reply
  97. ildarovich

    (99) Salavat,

    я тоже руку приложил к этому, немалую

    — в чем это можно заметить?

    Успокаиваться мне не нужно, так как я и так совершенно прав и оттого абсолютно спокоен. Просто некорректно и агрессивно себя ведете и мне нужно бы поставить Вас на место.

    Reply
  98. CheBurator

    (89) спасибо, буду очень ждать.

    просьба по возможности учесть чятоя нв 8-ке полный олух. могу только в пользовательском режиме кнопки нажимать.

    если взлетит — могу официальный отзыв дать от конторы о полезности.

    Reply
  99. CheBurator

    (89) и на этапе «отладочной» эксплуатации было бы хорошо визализацию раскладки видеть — как это у вас в обработке нарисовано.

    еще раз спасибо. буду ждать!!!!

    можно писать в личку или на мыло e.meil@mail.ru

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *