惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Recent Announcements
Recent Announcements
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
A
About on SuperTechFans
I
InfoQ
F
Full Disclosure
美团技术团队
Martin Fowler
Martin Fowler
量子位
V
V2EX
小众软件
小众软件
爱范儿
爱范儿
宝玉的分享
宝玉的分享
aimingoo的专栏
aimingoo的专栏
有赞技术团队
有赞技术团队
F
Fortinet All Blogs
M
MIT News - Artificial intelligence
T
Tailwind CSS Blog
博客园 - 三生石上(FineUI控件)
N
Netflix TechBlog - Medium
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
IT之家
IT之家
云风的 BLOG
云风的 BLOG
B
Blog RSS Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Hugging Face - Blog
Hugging Face - Blog
Microsoft Azure Blog
Microsoft Azure Blog
T
Threat Research - Cisco Blogs
T
Threatpost
P
Proofpoint News Feed
腾讯CDC
博客园 - 司徒正美
Jina AI
Jina AI
The Hacker News
The Hacker News
P
Privacy & Cybersecurity Law Blog
L
LINUX DO - 热门话题
S
Securelist
U
Unit 42
T
The Exploit Database - CXSecurity.com
博客园 - Franky
NISL@THU
NISL@THU
D
Docker
The GitHub Blog
The GitHub Blog
Latest news
Latest news
S
Schneier on Security
J
Java Code Geeks
Blog — PlanetScale
Blog — PlanetScale
P
Palo Alto Networks Blog

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Изометрия в 1С: склад стал интереснее, чем ваш сериал»
Михеев Антон · 2026-06-24 · via Все публикации подряд на Хабре

Что, если мы создадим такой интерфейс в 1С, чтобы он был удобнее, чем в Excel? Да не просто удобнее — а чтобы сотрудники сказали: «Ого, это же как игра!» С вами снова Ведущий специалист модуля разработки 1С Михеев Антон. Давайте вместе сделаем эту игру идею реальностью

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

Задачка: на стеллаже три полки. На первой — конфеты, на второй — печеньки, на третьей — сиропы.  Как пользователю понять, что нужно взять печеньку со второй полки?

Ответ: рисовать всю эту красоту в изометрии! Изометрия — это старая добрая технология, которая:

·         не нагружает процессор (в отличие от 3D, где ваш ПК может начать мечтать о пенсии);

·         позволяет рассмотреть предмет под углом в 30∘;

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

Как это сделать в 1С?

Здесь нам поможет встроенный редактор HTML внутри 1С. Если вы не знали, то 1С использует платформу WebKit, позаимствованную у айфонов (лучшие мировые практики, да).

Шаг 1. Создаём внешнюю обработку и добавляем в неё ПолеHTML документа.

Шаг 2. Создаём три макета: HTML, JS и CSS.

·         Макет HTML — это каркас страницы. Вставляем код:

html

<!DOCTYPE html>

<HTML>

<HEAD>@CSS</HEAD>

<BODY>

<h1>Изометрическая сетка 10 × 10 с перетаскиваемыми объектами</h1>

<div id='grid-container'></div>

@JS

</BODY>

</HTML>

·         Макет JS — это логика. Здесь мы:

o    создаём сетку из ячеек;

o    расставляем объекты (конфеты, печеньки, сиропы);

o    добавляем возможность перетаскивать их мышкой (drag & drop);

o    подсвечиваем ячейки при наведении;

o    проверяем, занята ли ячейка, прежде чем положить туда новый объект.

  • Добавим кода в макет:
    window.onload = function() {

  •     const gridContainer = document.getElementById('grid-container');

  •     const occupiedCells = new Set(); // Хранит занятые ячейки

  •     // Массив контейнеров с параметрами

  •     const containers = [@Containers];

  •     // Создаём ячейки сетки

  •     for (let i = 0; i < 10; i++) {

  •         for (let j = 0; j < 10; j++) {

  •             const cell = document.createElement('div');

  •             cell.className = 'cell';

  •             cell.style.left = ${j * 90}px;

  •             cell.style.top = ${i * 50}px;

  •             cell.dataset.row = i;

  •             cell.dataset.col = j;

  •             // Добавляем параметры x и y в качестве атрибутов ячейки

  •             cell.setAttribute('data-x', i);

  •             cell.setAttribute('data-y', j);

  •             gridContainer.appendChild(cell);

  •         }

  •     }

  •     // Расставляем объекты из массива контейнеров

  •     containers.forEach(container => {

  •         const item = document.createElement('div');

  •         item.className = 'draggable-item';

  •         item.textContent = container.text;

  •         item.draggable = true;

  •         item.style.backgroundColor = container.color;

  •         item.style.zIndex = parseInt(container.x / container.y * 100,10);

  •         const Top = document.createElement('div');

  •         Top.className = 'top';

  •         Top.textContent =  container.text;

  •         Top.style.backgroundColor = container.color;

  •         const Front = document.createElement('div');

  •         Front.className = 'front';

  •         Front.style.backgroundColor = container.color;

  •         const Right = document.createElement('div');

  •         Right.className = 'right';

  •         Right.textContent =  container.text;

  •         Right.style.backgroundColor = container.color;

  •         item.appendChild(Top);

  •         item.appendChild(Front);

  •         item.appendChild(Right);

  •         // Добавляем все параметры в качестве атрибутов draggable-item

  •         item.setAttribute('data-color', container.color);

  •         item.setAttribute('data-text', container.text);

  •         item.setAttribute('data-x', container.x);

  •         item.setAttribute('data-y', container.y);

  •         item.setAttribute('data-z', container.z);

  •         // Помещаем объект в ячейку согласно координатам x и y

  •         const targetCell = document.querySelector(.cell[data-row="${container.x}"][data-col="${container.y}"]);

  •         if (targetCell) {

  •             targetCell.appendChild(item);

  •             // Помечаем ячейку как занятую

  •             occupiedCells.add(${container.x},${container.y});

  •         }

  •     });

  •     let draggedItem = null;

  •     let originalCell = null;

  •     // Обработчик начала перетаскивания

  •     function handleDragStart(e) {

  •         draggedItem = this;

  •         originalCell = this.parentElement;

  •         e.dataTransfer.setData('text/plain', null);

  •         // Невидимость Ghost при перетаскивании

  •         var img = document.createElement("img");

  •         img.src = "";

  •         e.dataTransfer.setDragImage(img, 0, 0);

  •     }

  •     // Обработчик окончания перетаскивания

  •     document.addEventListener('dragend', () => {

  •         if (draggedItem) {

  •             draggedItem = null;

  •             originalCell = null;

  •         }

  •     });

  •     // Обработчики для всех ячеек сетки

  •     document.querySelectorAll('.cell').forEach(cell => {

  •         // Обработчик наведения — выделение фона и границы

  •         cell.addEventListener('mouseenter', () => {

  •             cell.style.backgroundColor = 'rgba(135, 206, 235, 0.3)'; // Полупрозрачный голубой

  •             cell.style.borderColor = 'blue';

  •             cell.style.zIndex = '10'; // Выводим поверх других элементов

  •             cell.style.boxShadow = '0 0 8px rgba(0, 123, 255, 0.5)'; // Дополнительная подсветка

  •         });

  •         cell.addEventListener('mouseleave', () => {

  •             // Восстанавливаем исходный вид

  •             cell.style.backgroundColor = '';

  •             cell.style.borderColor = '#999';

  •             cell.style.zIndex = '';

  •             cell.style.boxShadow = '';

  •         });

  •         cell.addEventListener('dragover', (e) => e.preventDefault());

  •         cell.addEventListener('drop', (e) => {

  •             e.preventDefault();

  •             if (!draggedItem) return;

  •             const row = cell.dataset.row;

  •             const col = cell.dataset.col;

  •             const cellKey = ${row},${col};

  •             // Проверяем, занята ли ячейка

  •             if (occupiedCells.has(cellKey)) {

  •                 alert('Ячейка уже занята! Выберите другую.');

  •                 return;

  •             }

  •             // Освобождаем предыдущую ячейку

  •             if (originalCell) {

  •                 const origRow = originalCell.dataset.row;

  •                 const origCol = originalCell.dataset.col;

  •                 occupiedCells.delete(${origRow},${origCol});

  •             }

  •             // Обновляем атрибуты draggable-item с новыми координатами

  •             draggedItem.setAttribute('data-x', row);

  •             draggedItem.setAttribute('data-y', col);

  •             // Помещаем объект в новую ячейку — он автоматически занимает всю площадь ячейки

  •             cell.appendChild(draggedItem);

  •             occupiedCells.add(cellKey);

  •         });

  •     });

  •     // Инициализируем обработчики перетаскивания для всех объектов на поле

  •     document.querySelectorAll('.draggable-item').forEach(item => {

  •         item.addEventListener('dragstart', handleDragStart);

  •     });

  •     document.querySelectorAll('.draggable-item').forEach(item => {

  •     item.addEventListener('mouseenter', () => {

  •         document.querySelectorAll('.draggable-item').forEach(otherItem => {

  •             if (otherItem !== item) {

  •                 otherItem.classList.add('dimmed');

  •             }

  •         });

  •     });

  •     item.addEventListener('mouseleave', () => {

  •         document.querySelectorAll('.draggable-item').forEach(otherItem => {

  •             otherItem.classList.remove('dimmed');

  •         });

  •     });

  • });

  •     // Запрещаем контекстное меню по правой кнопке мыши

  •     document.addEventListener('contextmenu', e => e.preventDefault());

  • }

·        
Макет CSS
 — это стиль. Здесь мы задаём цвета, размеры, тени, углы поворота и прочие красоты. Изометрия достигается через transform: rotate(-30deg) skewX(30deg) — магия, а не код!

Код на сервере: магия данных

В обработчике ПриСозданииНаСервере пишем код, который:

1.    Берёт макеты HTML, JS и CSS.

2.    Подставляет CSS и JS в HTML (через @CSS и @JS).

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

4.    Формирует массив контейнеров с параметрами (цвет, текст, координаты).

5.    Подставляет этот массив в HTML (вместо @Containers).

Добавим код ПриСозданииНаСервере:

bsl

ОбъектВнешнейОбработки = РеквизитФормыВЗначение("Объект");

                HTML = ОбъектВнешнейОбработки.ПолучитьМакет("МакетHTML").ПолучитьТекст();

                JS = "<script>" + ОбъектВнешнейОбработки.ПолучитьМакет("МакетJS").ПолучитьТекст() + "</script>";

                CSS = "<style>" + ОбъектВнешнейОбработки.ПолучитьМакет("МакетCSS").ПолучитьТекст() + "</style>";

                HTML = СтрЗаменить(HTML,"@CSS",CSS);

                HTML = СтрЗаменить(HTML,"@JS",JS); 

                //Тут пишем запрос который получит Координаты ячейки и Контейнер в ней            

                Запрос = Новый Запрос;

                Запрос.Текст =

                "ВЫБРАТЬ РАЗЛИЧНЫЕ

                |             укЗаполненностьЯчеекОстатки.Ячейка.Ряд КАК X,

                |             укЗаполненностьЯчеекОстатки.Ячейка.Ярус КАК Z,

                |             укЗаполненностьЯчеекОстатки.Ячейка.Позиция КАК Y

                |ИЗ

                |             РегистрНакопления.укЗаполненностьЯчеек.Остатки КАК укЗаполненностьЯчеекОстатки

                |ГДЕ

                |             укЗаполненностьЯчеекОстатки.Ячейка.Ряд < 10

                |             И укЗаполненностьЯчеекОстатки.Ячейка.Ярус = 1

                |             И укЗаполненностьЯчеекОстатки.Ячейка.Позиция < 10

                |

                |УПОРЯДОЧИТЬ ПО

                |             X Возр,

                |             Y ВОЗР";

                РезультатЗапроса = Запрос.Выполнить();

                Выборка = РезультатЗапроса.Выбрать();

                Результат = "";

                Пока Выборка.Следующий() Цикл

                               ТекСтрока = СтрШаблон("{ color: '#00008b', text: '%1', x: %2, y: %3, z: %4 },", "К-"+ Выборка.X + "-" + Выборка.Y , Выборка.X, Выборка.Y, Выборка.Z);

                               Результат = Результат + ТекСтрока;

                КонецЦикла;

                Результат = Лев(Результат, СтрДлина(Результат) - 1);

HTML = СтрЗаменить(HTML,"@Containers", Результат);

               
 «Запрос в 1С — это как заклинание: если произнести правильно, получишь желаемое. Если нет — получишь ошибку и желание всё бросить».

Что в итоге?

На выходе получается склад с изометрией! Ого, скажете вы, и будете правы. Это реально работает внутри 1С и не тормозит (в отличие от 3D, которое может заставить ваш компьютер задуматься о смысле жизни).

Что можно добавить:

·         Подсветку ячеек: красным — «Возьми отсюда», зелёным — «Поставь сюда».

·         Динамическую подгрузку задач на перемещение.

·         Отображение остатков прямо на контейнерах.

·         Уведомления: «Внимание! На полке с печеньками осталось 2 штуки!».

Получается уже не просто 1С, а почти игра!

Почему не 3D?

Вы спросите: «А почему не использовать 3D?» Ответ прост:

·         1С не сможет быстро выполнять качественный рендеринг моделей — всё будет тормозить.

·         Оптимизация 3D‑движка в 1С не даёт качественной детализации.

·         Возможность крутить камеру только сбивает пользователя.

 «3D в 1С — это как попытка запустить Cyberpunk 2077 на калькуляторе: идея крутая, но результат печальный».

Финальный аккорд

Зафиксируем угол для изометрии и прорисуем все объекты лишь под одним углом (максимум 4 картинки на объект). И вот он — весь склад перед вами, с хорошей детализацией, без тормозов и без необходимости изучать квантовую физику.

Как вам идейка? Удобно ли будет пользоваться детализированной интерактиивной топологией склада? 😉