Rambler's Top100
Форум: MS ACCESSVBVBA MS OfficeMS SQL server
Новые сообщения: 0000

Форум: MS ACCESS

Вопросы связанные с MS ACCESS

Обновить визитку
Участники «Online»
Все участники

 
 

Доброго времени суток, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: объединение нескольких строк в одну
 
 автор: lurix   (22.12.2009 в 14:39)   личное сообщение
 
 

Люди... начала забывать простые вещи...
Есть таблицы с 2 полями: Деталь (числовое поле); Примечание (текстовое поле).
Может быть так, что для одной и той же детали есь несколько примечаний (т.е.3 строки с повторяющейся запчасть и разными примечаниями).

Как создать запрос, в котором единоразово будет отображаться каждая деталь, а примечания будут объединяться?
Подскажите пожалуйста, как лучше сделать?

  Ответить  
 
 автор: kot_k_k   (22.12.2009 в 15:04)   личное сообщение
 
 

как на вскидку

запрос с функцией которая для каждой детали запускает обработку, вот со сваего сделал:
таблы - Naimen и Sklad


запрос

SELECT Naimen.Naimen, F_Ob([Kod_N]) AS Выражение1 FROM Naimen INNER JOIN Sklad ON Naimen.Kod_N = Sklad.Naimen;

код функции

Function F_Ob(ParamArray Ar())
Dim dbs As DAO.Database
Dim Nam As DAO.Recordset
Str_ = ""
Set dbs = CurrentDb
Set Nam = dbs.OpenRecordset("select * from sklad where naimen=" & Ar(0))
Do While Nam.EOF = False
    Str_ = Str_ & Nam!Prim
    Nam.MoveNext
Loop
F_Ob = Str_
End Function


а как одним запросом - если нароют лучше - сам поучусь

  Ответить  
 
 автор: lurix   (22.12.2009 в 15:33)   личное сообщение
 
 

а что такое Ar?

  Ответить  
 
 автор: kot_k_k   (22.12.2009 в 16:00)   личное сообщение
 
 

Ar() - массив параметров которые получает функция

  Ответить  
 
 автор: osmor   (22.12.2009 в 15:40)   личное сообщение
 
 

не такие уж и простые
http://hiprog.com/index.php?option=com_content&task=view&id=334&Itemid=35

  Ответить  
 
 автор: FORMAT   (22.12.2009 в 15:47)   личное сообщение
 
 

Если для скл сервера, то запросом тогда так



CREATE PROCEDURE _spYourProcedure


@Id int
AS
Declare @CursorComm nvarchar(300)
Declare @Com nvarchar(300)
DECLARE CurComm CURSOR FOR
SELECT Comm FROM Ваша таблица WHERE IdObj=@Id
SET @Com=''
OPEN CurComm
FETCH NEXT FROM CurComm INTO @CursorComm
WHILE @@FETCH_STATUS = 0

BEGIN

SELECT @Com = @Com + @CursorComm

FETCH NEXT FROM CurComm INTO @CursorComm
END
CLOSE CurComm
DEALLOCATE CurComm

SELECT @Com

/* SET NOCOUNT ON */
RETURN

  Ответить  
 
 автор: Силblч   (22.12.2009 в 15:47)   личное сообщение
 
 

Ю.Ш. рулит
а ты - молодец! :)

  Ответить  
 
 автор: lurix   (22.12.2009 в 16:19)   личное сообщение
 
 

Олег,
спасибо Вам большое!!!!!
Получилось!!!!
В данном случае как раз деталь не повторялась, а Примечания объединялись через запятую в одном поле.

Еще хотелось бы знать, как можно в запросе в каждом отдельном поле (тоже в строчку) показать значение поля Примечание?

  Ответить  
 
 автор: Силblч   (22.12.2009 в 15:45)   личное сообщение
 
 

если написать вот такую функцию

Public Function qlist(idd&, note$)
Static s$
Static id&
If Nz(id, 0) <> Nz(idd, 0) Then
    id = idd: s = note
Else
    s = s & "|" & note
End If
qlist = s
End Function


для таблицы такой структуры


idd    note
1    описание1_1
1    описание1_2
1    описание1_3
2    описание2_1
2    описание2_2
3    описание3_1
4    описание4_1
5    описание5_1
5    описание5_2


и воткнуть её вот в такой запрос:

SELECT детали.idd, Max(qlist([idd],[note])) AS Выражение1
FROM детали
GROUP BY детали.idd;


дал мне вот такой результат вывело:

idd    Выражение1
1    описание1_1|описание1_2|описание1_3
2    описание2_1|описание2_2
3    описание3_1
4    описание4_1
5    описание5_1|описание5_2

  Ответить  
 
 автор: kot_k_k   (22.12.2009 в 16:20)   личное сообщение
 
 

решил применить к своему - проверить типа
скопировал ф-цию, постоил запрос - орет про "Несоответствие типов данных в выражениии условия отбора"

пробовал уборать группировку - в Выражении1 пишет #Ошибка. а до точки останова в функции не доходит.

Добавлено:
протупил - убрал $ и & в функции - пошло.

  Ответить  
 
 автор: lurix   (22.12.2009 в 16:43)   личное сообщение
 
 

так тоже получилось, а возможно ли их разбить по полям вместо "I"?

  Ответить  
 
 автор: Lukas   (22.12.2009 в 17:09)   личное сообщение
 
 

Можно, но долго.
У меня на 17848 значениях примечаний, при 2000 родителей, запрос выполнялся 1 мин 25 сек.
Правда это все в-лоб, без оптимизации.

  Ответить  
 
 автор: lurix   (22.12.2009 в 17:13)   личное сообщение
 
 

подскажите, как это сделать?
т.к.CrossTab - не подходит - детали выводятся как названия столбцов...(((

  Ответить  
 
 автор: Lukas   (22.12.2009 в 17:22)   личное сообщение
 
 

Для CrossTab нам нужно сделать расчетное поле с помощью VBA функции, которое должно
выдавать последовательные порядковые номера для примечаний в пределах одного родителя. (1, 2, 3 и т.д.)

Public Function acbGenPOSID(Optional ID As Variant) As Long
Static lngPrevPOSID As Long
Static lngPrevID As Long

    If IsMissing(ID) Then
        lngPrevPOSID = 0
        acbGenPOSID = -1
        Exit Function
    End If
    If ID <> lngPrevID Then
        lngPrevPOSID = 0
        lngPrevID = ID
    End If
    lngPrevPOSID = lngPrevPOSID + 1
    acbGenPOSID = lngPrevPOSID
End Function


Ну а далее CrossTab

TRANSFORM First(t1.ChildName) AS [First-ChildName]
SELECT t1.IDParent, t1.ParentName
FROM (
SELECT tblParent.IDParent, tblParent.ParentName, acbGenPOSID(tblParent.IDParent) AS Num, tblChild.ChildName
FROM tblParent LEFT JOIN tblChild ON tblParent.IDParent=tblChild.IDParent
WHERE acbGenPOSID()
) As t1
GROUP BY t1.IDParent, t1.ParentName
PIVOT t1.Num;

Конечно, все это еще надо причесать рашпилем, а может и вообще в топку.

  Ответить  
 
 автор: lurix   (22.12.2009 в 17:29)   личное сообщение
 
 

не получается....
Можно ли сделать такую выборку в обычном запросе?

  Ответить  
 
 автор: Lukas   (22.12.2009 в 17:56)   личное сообщение
59 Кб.
 
 

А у меня почти получается, скрин:

Может необходимо добавить сортировку в запрос:
TRANSFORM First(t1.ChildName) AS [First-ChildName]
SELECT t1.IDParent, t1.ParentName
FROM (
SELECT tblParent.IDParent, tblParent.ParentName, acbGenPOSID(tblParent.IDParent) AS Num, tblChild.ChildName
FROM tblParent LEFT JOIN tblChild ON tblParent.IDParent=tblChild.IDParent
WHERE acbGenPOSID()
ORDER BY tblParent.IDParent
) AS t1
GROUP BY t1.IDParent, t1.ParentName
PIVOT t1.Num;

  Ответить  
HiProg.com - Технологии программирования
Rambler's Top100 TopList