Форум программистов, компьютерный форум, киберфорум
PostgreSQL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 1
Регистрация: 27.06.2013
Сообщений: 88

Вывод древовидной иерархии в виде JSON

27.06.2025, 16:04. Показов 1481. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте дорогие форумчане. Прошу вас подсказать мне. Мне нужно имея таблицу отделов вернуть из бд json дерево по отделам.
У меня есть такая вот таблица:


Мне нужно написать рекурсивный запрос по этой таблице и получить результат в виде json:
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{[
  {"departmentId": 0,
   "departmentName": "Отдел 1",
        "children": [
          {"departmentId": 1,
           "departmentName": "Отдел 1.1",
           "children": [
               {
                 "departmentId": 2,
                 "departmentName": "Отдел 1.1.1",
                 "children": [
                     {
                       "departmentId": 5,
                       "departmentName": "Отдел 1.1.1.1",
                       "children": "null"
                     }
                   ]
               }
             ]
          }],
          {"departmentId": 3,
           "departmentName": "Отдел 2",
           "children":[
             {"departmentId": 4,
              "departmentName": "Отдел 2.1",
              "children": "null"
             }
          ]
         }
  }
]}
посмотрев в интенерте рекурсивные запросы я сделала такой вот запрос:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
WITH recursive parents AS (
 
  SELECT
    id, name, parent_id
  FROM departments
  WHERE
    id = '798c66092ef24ec488ef308291947913'
 
  UNION ALL
 
  SELECT
    dep.id, dep.name, dep.parent_id
  FROM departments dep
  JOIN parents ON parents.parent_id = dep.id
)
 
SELECT
  *
FROM parents
WHERE id != '798c66092ef24ec488ef308291947913'
--order by id;
Но этот запрос мне возвращает только родителей отдела по id. Т.е. он ищет всех родителей переданного отдела.
Как его передлать чтобы он мне вернула такой json ?
Я пробовлаа по-разному сделать, разные примеры пересмотерла, но никак не могу получить себе такой вот json...
Могли бы вы, пожалуйста, подсказать мне, как написать такой запрос ?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
27.06.2025, 16:04
Ответы с готовыми решениями:

Хранение древовидной информации
Как организовать хранение 'древовидной' информации (структура предприятия,структура документации и...

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

Запрос К Таблице С Древовидной Структурой
Есть две таблицы. Одна с древовидной структурой: ID SUBID NAME 1 0 Автомобили 2 1 Lada 3 1...

4
0 / 0 / 0
Регистрация: 03.07.2025
Сообщений: 2
06.07.2025, 20:14
Если имелась ввиду структура каталогов (что логично):

Отдел 1 (ID: 0)
--Отдел 1.1 (ID: 1)
----Отдел 1.1.1 (ID: 2)
------Отдел 1.1.1.1 (ID: 5)
Отдел 2 (ID: 3)
--Отдел 2.1 (ID: 4)

json должен быть таким:
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
[
  {
    "departmentId": 0,
    "departmentName": "Отдел 1",
    "children": [
      {
        "departmentId": 1,
        "departmentName": "Отдел 1.1",
        "children": [
          {
            "departmentId": 2,
            "departmentName": "Отдел 1.1.1",
            "children": [
              {
                "departmentId": 5,
                "departmentName": "Отдел 1.1.1.1",
                "children": "null"
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "departmentId": 3,
    "departmentName": "Отдел 2",
    "children": [
      {
        "departmentId": 4,
        "departmentName": "Отдел 2.1",
        "children": "null"
      }
    ]
  }
]


Один из многих вариантов, как получить такой json вне зависимости от глубины уровней иерархии:

SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
DROP TABLE IF EXISTS departments;
 
-- Создание таблицы
CREATE TABLE departments (
  id INT PRIMARY KEY,
  parent_id INT REFERENCES departments(id),
  name text NOT NULL
);
 
-- Вставка данных
INSERT INTO departments (id, parent_id, name) VALUES
    (0, NULL, 'Отдел 1'),
    (1, 0, 'Отдел 1.1'),
    (2, 1, 'Отдел 1.1.1'),
    (3, NULL, 'Отдел 2'),
    (4, 3, 'Отдел 2.1'),
    (5, 2, 'Отдел 1.1.1.1')
;
 
WITH RECURSIVE tree AS (
-- Начинаем с корневых узлов (parent_id IS NULL)
  SELECT
    id AS root_id,
    id AS parent_id,
    id AS child_id,
    name AS parent_name,
    name AS child_name,
    0 AS node_level
    FROM departments
    WHERE parent_id IS NULL
    
    UNION ALL
  -- Рекурсивно добавляем дочерние узлы
    SELECT
        t.root_id,
        t.child_id AS parent_id,
        d.id AS child_id,
        t.child_name AS parent_name,
        d.name AS child_name,
        t.node_level + 1
    FROM departments d
    INNER JOIN tree t ON d.parent_id = t.child_id
)
,
 
-- Строим плоскую таблицу дерева, где одна запись - один уровень
 
full_tree AS (
    SELECT
        root_id,
        node_level,
        parent_id,
        parent_name,
        child_id,
        child_name
    FROM tree
    WHERE node_level > 0
    )
 
-- Собираем json "вручную"
 
SELECT
    '[' || string_agg(json_record, ',') || ']' json_file
FROM
    (
      SELECT
      root_id,
      string_agg(
      nodes
      || '", "children": "null"'
      || repeat('}]', (SELECT COUNT(*) FROM full_tree t2 WHERE t1.root_id = t2.root_id)::INT) || '}', '') json_record
      FROM
        (
          SELECT
            root_id,
            string_agg
                (
                  CASE
                    WHEN node_level = 1 THEN
                      '{"departmentID": '
                      || parent_id::text
                      || ', "departmentName": "'
                      || parent_name
                      || '","children": [{"departmentID": '
                      || child_id::text
                      || ', "departmentName": "'
                      || child_name
                    ELSE
                      '","children": [{"departmentID": '
                      || child_id::text
                      || ', "departmentName": "'
                      || child_name
                    END, ','
                    ) nodes
                FROM full_tree
              GROUP BY root_id
          ) t1
        GROUP BY root_id
    ) r
;
0
0 / 0 / 1
Регистрация: 27.06.2013
Сообщений: 88
07.07.2025, 13:42  [ТС]
спасибо большое за ответ! Это то что нужно))
0
0 / 0 / 0
Регистрация: 03.07.2025
Сообщений: 2
07.07.2025, 21:03
Не за что! Вообще-то говоря, это "костыль" :-) По-хорошему делать надо так:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
-- Удаление старой таблицы (если существует)
DROP TABLE IF EXISTS departments;
 
-- Создание таблицы
CREATE TABLE departments (
    id INT PRIMARY KEY,
    parent_id INT REFERENCES departments(id),
    name text NOT NULL
);
 
-- Вставка данных
INSERT INTO departments (id, parent_id, name) VALUES
(0, NULL, 'Отдел 1'),
(1, 0, 'Отдел 1.1'),
(2, 1, 'Отдел 1.1.1'),
(3, NULL, 'Отдел 2'),
(4, 3, 'Отдел 2.1'),
(5, 3, 'Отдел 2.2'),
(6, 2, 'Отдел 1.1.1.1'),
(7, NULL, 'Отдел 3'),
(8, 7, 'Отдел 3.1'),
(9, 7, 'Отдел 3.2'),
(10, 8, 'Отдел 3.1.1'),
(11, 8, 'Отдел 3.1.2'),
(12, 9, 'Отдел 3.2.1'),
(13, 9, 'Отдел 3.2.2'),
(14, 9, 'Отдел 3.2.3'),
(15, 4, 'Отдел 2.1.1'),
(16, 4, 'Отдел 2.1.2'),
(17, 5, 'Отдел 2.2.1'),
(18, NULL, 'Отдел 4'),
(19, NULL, 'Отдел 5'),
(20, 19, 'Отдел 5.1'),
(21, 20, 'Отдел 5.1.1'),
(22, 6, 'Отдел 1.1.1.1.1'),
(24, 22, 'Отдел 1.1.1.1.1.1'),
(25, 11, 'Отдел 3.1.2.1'),
(26, 17, 'Отдел 2.2.1.1'),
(27, 18, 'Отдел 4.1'),
(28, 21, 'Отдел 5.1.1.1'),
(29, 19, 'Отдел 5.2')
;
 
-- Создание функции
CREATE OR REPLACE FUNCTION build_tree()
RETURNS jsonb AS $$
DECLARE
    RESULT jsonb;
    processed_count INTEGER;
    unprocessed_count INTEGER;
BEGIN
    -- Создаем временную таблицу для хранения JSON узлов
    CREATE TEMP TABLE temp_tree (
        id INT PRIMARY KEY,
        parent_id INT,
        name text,
        level INT,
        json_data jsonb,
        processed BOOLEAN DEFAULT FALSE
    ) ON COMMIT DROP;
 
    -- Заполняем таблицу всеми отделами
    INSERT INTO temp_tree
    SELECT 
        d.id,
        d.parent_id,
        d.name,
        0, -- Уровень обновим позже
        NULL, -- JSON построим позже
        FALSE
    FROM departments d;
 
    -- Обновляем уровни иерархии рекурсивно
    WITH RECURSIVE level_calc AS (
        SELECT id, parent_id, name, 0 AS level
        FROM departments
        WHERE parent_id IS NULL
        
        UNION ALL
        
        SELECT 
            d.id,
            d.parent_id,
            d.name,
            lc.level + 1
        FROM departments d
        JOIN level_calc lc ON d.parent_id = lc.id
    )
    UPDATE temp_tree tt
    SET level = lc.level
    FROM level_calc lc
    WHERE tt.id = lc.id;
 
    -- Обрабатываем листовые узлы (без детей)
    UPDATE temp_tree tt
    SET 
        json_data = jsonb_build_object(
            'id', tt.id,
            'name', tt.name,
            'children', NULL::jsonb
        ),
        processed = TRUE
    WHERE NOT EXISTS (
        SELECT 1 FROM departments d WHERE d.parent_id = tt.id
    );
 
    -- Итеративно обрабатываем остальные узлы снизу вверх
    LOOP
        -- Обрабатываем узлы, у которых все дети уже обработаны
        UPDATE temp_tree parent
        SET 
            json_data = jsonb_build_object(
                'id', parent.id,
                'name', parent.name,
                'children', COALESCE(
                    (SELECT jsonb_agg(child.json_data ORDER BY child.id)
                     FROM temp_tree child
                     WHERE child.parent_id = parent.id),
                    '[]'::jsonb
                )
            ),
            processed = TRUE
        WHERE parent.processed = FALSE
        AND NOT EXISTS (
            SELECT 1 
            FROM temp_tree child
            WHERE child.parent_id = parent.id
            AND child.processed = FALSE
        );
 
        -- Проверяем, сколько узлов осталось обработать
        SELECT COUNT(*) INTO processed_count FROM temp_tree WHERE processed = TRUE;
        SELECT COUNT(*) INTO unprocessed_count FROM temp_tree WHERE processed = FALSE;
        
        -- Выходим из цикла, когда все узлы обработаны
        EXIT WHEN unprocessed_count = 0;
        
        -- Защита от бесконечного цикла
        IF processed_count = 0 THEN
            RAISE EXCEPTION 'Обнаружена циклическая зависимость в иерархии отделов';
        END IF;
    END LOOP;
 
    -- Собираем финальный результат из корневых узлов
    SELECT jsonb_agg(json_data ORDER BY id)
    INTO RESULT
    FROM temp_tree
    WHERE parent_id IS NULL;
 
    RETURN RESULT;
END;
$$ LANGUAGE plpgsql;
 
-- Вызываем функцию
SELECT jsonb_pretty(build_tree()) AS department_tree;

Собственно, json

JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
[
  {
    "id": 0,
    "name": "Отдел 1",
    "children": [
      {
        "id": 1,
        "name": "Отдел 1.1",
        "children": [
          {
            "id": 2,
            "name": "Отдел 1.1.1",
            "children": [
              {
                "id": 6,
                "name": "Отдел 1.1.1.1",
                "children": [
                  {
                    "id": 22,
                    "name": "Отдел 1.1.1.1.1",
                    "children": [
                      {
                        "id": 24,
                        "name": "Отдел 1.1.1.1.1.1",
                        "children": null
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "id": 3,
    "name": "Отдел 2",
    "children": [
      {
        "id": 4,
        "name": "Отдел 2.1",
        "children": [
          {
            "id": 15,
            "name": "Отдел 2.1.1",
            "children": null
          },
          {
            "id": 16,
            "name": "Отдел 2.1.2",
            "children": null
          }
        ]
      },
      {
        "id": 5,
        "name": "Отдел 2.2",
        "children": [
          {
            "id": 17,
            "name": "Отдел 2.2.1",
            "children": [
              {
                "id": 26,
                "name": "Отдел 2.2.1.1",
                "children": null
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "id": 7,
    "name": "Отдел 3",
    "children": [
      {
        "id": 8,
        "name": "Отдел 3.1",
        "children": [
          {
            "id": 10,
            "name": "Отдел 3.1.1",
            "children": null
          },
          {
            "id": 11,
            "name": "Отдел 3.1.2",
            "children": [
              {
                "id": 25,
                "name": "Отдел 3.1.2.1",
                "children": null
              }
            ]
          }
        ]
      },
      {
        "id": 9,
        "name": "Отдел 3.2",
        "children": [
          {
            "id": 12,
            "name": "Отдел 3.2.1",
            "children": null
          },
          {
            "id": 13,
            "name": "Отдел 3.2.2",
            "children": null
          },
          {
            "id": 14,
            "name": "Отдел 3.2.3",
            "children": null
          }
        ]
      }
    ]
  },
  {
    "id": 18,
    "name": "Отдел 4",
    "children": [
      {
        "id": 27,
        "name": "Отдел 4.1",
        "children": null
      }
    ]
  },
  {
    "id": 19,
    "name": "Отдел 5",
    "children": [
      {
        "id": 20,
        "name": "Отдел 5.1",
        "children": [
          {
            "id": 21,
            "name": "Отдел 5.1.1",
            "children": [
              {
                "id": 28,
                "name": "Отдел 5.1.1.1",
                "children": null
              }
            ]
          }
        ]
      },
      {
        "id": 29,
        "name": "Отдел 5.2",
        "children": null
      }
    ]
  }
]
Добавлено через 2 часа 2 минуты
В качестве бонуса немного модернизированная версия функции, которой можно передать 2 параметра:
root_id: позволяет выбрать поддерево
pretty: переключает вывод json между компактным и форматированным

SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
-- Удаление старой версии функции (если существует)
DROP FUNCTION IF EXISTS build_tree_param(INT, BOOLEAN);
 
-- Создание функции с двумя параметрами: root_id и pretty
CREATE OR REPLACE FUNCTION build_tree_param(root_id INT DEFAULT NULL, pretty BOOLEAN DEFAULT FALSE)
RETURNS text AS $$
DECLARE
    RESULT jsonb;
    processed_count INTEGER;
    unprocessed_count INTEGER;
BEGIN
    -- Создаем временную таблицу для хранения JSON узлов
    CREATE TEMP TABLE temp_tree (
        id INT PRIMARY KEY,
        parent_id INT,
        name text,
        level INT,
        json_data jsonb,
        processed BOOLEAN DEFAULT FALSE
    ) ON COMMIT DROP;
 
    -- Заполняем таблицу только теми узлами, которые принадлежат к нужному поддереву
    INSERT INTO temp_tree
    SELECT 
        d.id,
        d.parent_id,
        d.name,
        0,
        NULL,
        FALSE
    FROM departments d
    WHERE root_id IS NULL
       OR d.id = root_id
       OR d.id IN (
            WITH RECURSIVE subtree AS (
                SELECT id, parent_id FROM departments WHERE id = root_id
                UNION ALL
                SELECT d.id, d.parent_id FROM departments d
                INNER JOIN subtree s ON d.parent_id = s.id
            )
            SELECT id FROM subtree
        );
 
    -- Если root_id задан, но не найден — возвращаем пустой массив
    IF root_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM departments WHERE id = root_id) THEN
        RETURN NULL::jsonb;
    END IF;
 
    -- Обновляем уровни иерархии рекурсивно
    WITH RECURSIVE level_calc AS (
        SELECT id, parent_id, name, 0 AS level
        FROM departments
        WHERE (root_id IS NULL AND parent_id IS NULL)
           OR (root_id IS NOT NULL AND id = root_id)
        
        UNION ALL
        
        SELECT 
            d.id,
            d.parent_id,
            d.name,
            lc.level + 1
        FROM departments d
        JOIN level_calc lc ON d.parent_id = lc.id
        WHERE root_id IS NULL OR d.id IN (
            WITH RECURSIVE subtree AS (
                SELECT id, parent_id FROM departments WHERE id = root_id
                UNION ALL
                SELECT d.id, d.parent_id FROM departments d
                INNER JOIN subtree s ON d.parent_id = s.id
            )
            SELECT id FROM subtree
        )
    )
    UPDATE temp_tree tt
    SET level = lc.level
    FROM level_calc lc
    WHERE tt.id = lc.id;
 
    -- Обрабатываем листовые узлы (без детей)
    UPDATE temp_tree tt
    SET 
        json_data = jsonb_build_object(
            'id', tt.id,
            'name', tt.name,
            'children', NULL::jsonb
        ),
        processed = TRUE
    WHERE NOT EXISTS (
        SELECT 1 FROM departments d WHERE d.parent_id = tt.id
    );
 
    -- Итеративно обрабатываем остальные узлы снизу вверх
    LOOP
        -- Обрабатываем узлы, у которых все дети уже обработаны
        UPDATE temp_tree parent
        SET 
            json_data = jsonb_build_object(
                'id', parent.id,
                'name', parent.name,
                'children', COALESCE(
                    (SELECT jsonb_agg(child.json_data ORDER BY child.id)
                     FROM temp_tree child
                     WHERE child.parent_id = parent.id),
                    '[]'::jsonb
                )
            ),
            processed = TRUE
        WHERE parent.processed = FALSE
          AND NOT EXISTS (
              SELECT 1 
              FROM temp_tree child
              WHERE child.parent_id = parent.id
                AND child.processed = FALSE
          );
 
        -- Проверяем, сколько узлов осталось обработать
        SELECT COUNT(*) INTO processed_count FROM temp_tree WHERE processed = TRUE;
        SELECT COUNT(*) INTO unprocessed_count FROM temp_tree WHERE processed = FALSE;
        
        -- Выходим из цикла, когда все узлы обработаны
        EXIT WHEN unprocessed_count = 0;
        
        -- Защита от бесконечного цикла
        IF processed_count = 0 THEN
            RAISE EXCEPTION 'Обнаружена циклическая зависимость в иерархии отделов';
        END IF;
    END LOOP;
 
    -- Собираем финальный результат:
    -- Если root_id задан, возвращаем только его узел
    IF root_id IS NOT NULL THEN
        SELECT json_data INTO RESULT
        FROM temp_tree
        WHERE id = root_id;
    ELSE
        SELECT jsonb_agg(json_data ORDER BY id)
        INTO RESULT
        FROM temp_tree
        WHERE parent_id IS NULL;
    END IF;
 
    -- Форматируем результат в зависимости от параметра pretty
    IF pretty THEN
        RETURN jsonb_pretty(RESULT);
    ELSE
        RETURN RESULT;
    END IF;
END;
$$ LANGUAGE plpgsql;

Варианты запуска:

SQL
1
2
3
4
SELECT build_tree_param(); -- выводит полное дерево
SELECT build_tree_param(pretty => TRUE); -- выводит полное дерево с форматированием
SELECT build_tree_param(3); -- выводит поддерево, начиная с ID = 3
SELECT build_tree_param(7, TRUE); -- выводит поддерево, начиная с ID = 7, с форматированием
0
0 / 0 / 1
Регистрация: 27.06.2013
Сообщений: 88
09.07.2025, 10:41  [ТС]
супер! Спасибо вам огромное)) я пока не так много умею писать разнообразных запросов, с рекурсией не приходилось работать в SQL. Поэтому долго возилась, пытаясь сделать подобную функцию. Очень благодарна вам.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.07.2025, 10:41
Помогаю со студенческими работами здесь

Запрос К Таблице С Древовидной Структурой
Есть две таблицы. Одна с древовидной структурой: ID SUBID NAME 1 0 Автомобили 2 1 Lada 3 1...

Подскажите идеи по созданию древовидной структуры записи
Добрый вечер, уважаемые форумчане!! Необходимо реализовать некий журнал , в котором будут...

Изменения в древовидной структуре
Доброго дня, форумчане! Передо мной возникла такая задача. Из таблиц, которые редактирует...

Экспорт из базы Access в таблицу Excel с древовидной структурой
Доброго времени суток. Есть задача выгрузить прайс-лист из access в таблицу excel с древовидной...

Создание древовидной БД
Задача вот в чем: Товары базы сгруппированы по категориям. Категории организованы в древовидную...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru