Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Access
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.03.2018, 23:24   #1
Aleksandr H.
2 the Nation Glory
Старожил
 
Аватар для Aleksandr H.
 
Регистрация: 27.05.2014
Сообщений: 3,289
По умолчанию Преобразовать таблицу

Есть таблица, надо из нее получить другую таблицу.
ATT.jpg
Как верно назвать ето хз, на фирме зовется "плоская норма".
Сейчас решается с помощью каскада запросов SKU-subSKU,
Код:
sku
subSKU---sku
         subSKU---sku
                  subSKU
не удобно с масштабированием, если будут добавляться уровни, придется дописывать новые запросы.

Может будут идеи как сделать? имхо надо рекурсивно перебирать записи, но как организовать не знаю.


p.s.
Если есть более осмысленное название топика, прошу переименовать
Кто умер, но не забыт, тот бессмертен.
Лао-Цзы.
Aleksandr H. вне форума Ответить с цитированием
Старый 05.03.2018, 23:38   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Просто запросом в access не получится. Но в vba то можно рекурсивную функцию наваять, или цикл использовать для построения той таблицы
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 06.03.2018, 06:39   #3
shanemac51
Участник клуба
 
Аватар для shanemac51
 
Регистрация: 12.08.2010
Сообщений: 1,077
По умолчанию

Цитата:
Сообщение от Aleksandr H. Посмотреть сообщение
Есть таблица, надо из нее получить другую таблицу
похоже на состав изделия
и сколько уровней вхождения может быть
Имя-Галина== почта shanemac51@yandex.ru скайп shanemac51 c 8-15мск будни
Сфера интересов--word-excel-access-распознавание
shanemac51 вне форума Ответить с цитированием
Старый 06.03.2018, 07:20   #4
Aleksandr H.
2 the Nation Glory
Старожил
 
Аватар для Aleksandr H.
 
Регистрация: 27.05.2014
Сообщений: 3,289
По умолчанию

Цитата:
Сообщение от shanemac51 Посмотреть сообщение
похоже на состав изделия
Вы правы, это состав изделия
Цитата:
Сообщение от shanemac51 Посмотреть сообщение
и сколько уровней вхождения может быть
сейчас от 2 до 6
Кто умер, но не забыт, тот бессмертен.
Лао-Цзы.
Aleksandr H. вне форума Ответить с цитированием
Старый 06.03.2018, 12:06   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

На vba лень и в облом писать, редко пользуюсь. Но алгоритм рекурсии можно и на делфи показать, не так ли?

TableIn:
Код:
Sku     subSku
0	1
1	5
1	6
0	2
2	3
3	4
0	3
Код:
procedure TForm1.Creater(Level: Integer);
var s1,s2: String;
    i: Integer;
begin
  if Level=0 then begin
    ADOQuery2.SQL.Text:=
      'INSERT INTO TableOut (Sku,Lvl1)'+
      ' SELECT Sku,subSku FROM TableIn';
    ADOQuery2.ExecSQL;
  end
  else begin
    ADOQuery1.Active:=False;
    ADOQuery1.SQL.Text:=
      'SELECT T1.Lvl'+IntToStr(Level)+' AS Sku,T2.Lvl1 AS Lv'+
      ' FROM TableOut T1 INNER JOIN TableOut T2 ON T1.Lvl'+IntToStr(Level)+'=T2.Sku'+
      ' GROUP BY T1.Lvl'+IntToStr(Level)+',T2.Lvl1';
    ADOQuery1.Open;
    ADOQuery1.Last;
    if ADOQuery1.RecordCount=0 then Exit;

    ADOQuery2.SQL.Text:=
      'UPDATE TableOut'+
      ' SET Lvl'+IntToStr(Level+1)+'=T2.Lvl1'+
      ' FROM TableOut INNER JOIN TableOut T2 ON TableOut.Lvl'+IntToStr(Level)+'=T2.Sku';
    ADOQuery2.ExecSQL;

    s1:='';
    s2:='';
    for i:=2 to Level+1 do begin
      s1:=s1+',Lvl'+IntToStr(i);
      if i<Level+1 then s2:=s2+',T1.Lvl'+IntToStr(i);
    end;
    ADOQuery2.SQL.Text:=
      'INSERT INTO TableOut (Sku,Lvl1'+s1+')'+
      ' SELECT T1.Sku,T1.Lvl1'+s2+',T2.Lvl1'+
      '  FROM TableOut T1 INNER JOIN TableOut T2 ON T1.Lvl'+IntToStr(Level)+'=T2.Sku AND T1.Lvl'+IntToStr(Level+1)+'<>T2.Lvl1';
    ADOQuery2.ExecSQL;
  end;
  Creater(Level+1);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ADOQuery2.SQL.Text:='DELETE FROM TableOut';
  ADOQuery2.ExecSQL;
  Creater(0);
end;
TableOut:
Код:
Sku     Lvl1    Lvl2    Lvl3    Lvl4    Lvl5
0	1	5	NULL	NULL	NULL
1	5	NULL	NULL	NULL	NULL
1	6	NULL	NULL	NULL	NULL
0	2	3	4	NULL	NULL
2	3	4	NULL	NULL	NULL
3	4	NULL	NULL	NULL	NULL
0	3	4	NULL	NULL	NULL
0	1	6	NULL	NULL	NULL
Да и таблички на сиквеле, поэтому для access могут быть нюансы в части update с from - не помню как access на это среагирует. Понятно, что на таком объеме тестирования может и не все учел ))

ADD

последний insert вызывает подозрения - скорее всего дубли будут, например в TableIn добавить 1, 7. С помощью group by там же наверно и избавиться можно от них
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 06.03.2018 в 12:28.
Аватар вне форума Ответить с цитированием
Старый 06.03.2018, 16:45   #6
Aleksandr H.
2 the Nation Glory
Старожил
 
Аватар для Aleksandr H.
 
Регистрация: 27.05.2014
Сообщений: 3,289
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
последний insert вызывает подозрения
Что он должен сделать? Добавить записи или столбцы в таблицу?


Непонятно как в 2 параметра, (Sku,Lvl1'+s1+')' занести 3 (T1.Sku,T1.Lvl1'+s2+',T2.Lvl1)

Код:
...
'INSERT INTO TableOut (Sku,Lvl1'+s1+')'+
      ' SELECT T1.Sku,T1.Lvl1'+s2+',T2.Lvl1'+....
Кто умер, но не забыт, тот бессмертен.
Лао-Цзы.
Aleksandr H. вне форума Ответить с цитированием
Старый 06.03.2018, 16:56   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Цитата:
Непонятно как в 2 параметра
там же if i<Level+1, поэтому в s2 на один меньше добавляется, в итоге все ok
Цитата:
Добавить записи или столбцы в таблицу
insert же, значит записи добавляет. Добавить столбец alter table нужно, я и не добавлял, хотя в принципе ни чего не мешает в этой же процедуре добавлять столбцы в TableOut. У меня просто заранее созданная табличка c достаточным количеством столбцов
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 06.03.2018 в 16:59.
Аватар вне форума Ответить с цитированием
Старый 06.03.2018, 17:06   #8
Aleksandr H.
2 the Nation Glory
Старожил
 
Аватар для Aleksandr H.
 
Регистрация: 27.05.2014
Сообщений: 3,289
По умолчанию

В блок if i< Level+1 не попадаю на Level == 1
дальше получаю
Код:
ІNSERT INTO TableOut (Sku,Lvl1)  SELECT T1.Sku,T1.Lvl1,T2.Lvl1 ...
Цитата:
Сообщение от Аватар Посмотреть сообщение
У меня просто заранее созданная табличка c достаточным количеством столбцов
Кто умер, но не забыт, тот бессмертен.
Лао-Цзы.
Aleksandr H. вне форума Ответить с цитированием
Старый 06.03.2018, 17:14   #9
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Почему у меня для level=1 получается
Код:
INSERT INTO TableOut (Sku,Lvl1,Lvl2) SELECT T1.Sku,T1.Lvl1,T2.Lvl1 ...
внимательней как s1 и s2 заполняется и куда помещается ))
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 06.03.2018, 17:23   #10
Aleksandr H.
2 the Nation Glory
Старожил
 
Аватар для Aleksandr H.
 
Регистрация: 27.05.2014
Сообщений: 3,289
По умолчанию

Как говорится "сломал глаза, не вижу"

Код:
s1:='';
s2:='';
    
//Level == 1, в следующий блок не попадаю
for i:=2 to Level+1 do begin
      s1:=s1+',Lvl'+IntToStr(i);
      if i<Level+1 then s2:=s2+',T1.Lvl'+IntToStr(i);
end;
// следовательно s1 = "" i s2 = ""
    
ADOQuery2.SQL.Text:=
      'INSERT INTO TableOut (Sku,Lvl1'+s1+')'+ // INSERT INTO TableOut (Sku, Lvl1) //т.к. s1 == ""
      ' SELECT T1.Sku,T1.Lvl1'+s2+',T2.Lvl1'+  // SELECT T1.Sku, T1.Lvl1, T2.Lvl1  //т.к. s2 == ""
      
  '  FROM TableOut T1 INNER JOIN TableOut T2 ON T1.Lvl'+IntToStr(Level)+'=T2.Sku AND T1.Lvl'+IntToStr(Level+1)+'<>T2.Lvl1';
ADOQuery2.ExecSQL;
Кто умер, но не забыт, тот бессмертен.
Лао-Цзы.
Aleksandr H. вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
помогите пожалуйста (Организовать таблицу как хэш – таблицу) Владимир123321 C# (си шарп) 0 23.09.2013 14:44
Преобразовать таблицу SlimFIT Microsoft Office Excel 2 17.10.2012 14:47
Преобразовать в локальную таблицу GES Microsoft Office Access 3 07.09.2012 10:09
Преобразовать таблицу(Вопрос от новичка) Citizen^K Microsoft Office Excel 3 10.02.2010 11:53
VBA Преобразовать в диапазон таблицу king13 Microsoft Office Excel 4 16.10.2009 11:08