Aparatentemente o seu select está O.K. (sendo os "JOINs" da sua exclusiva responsabilidade).
Se existem registos duplicados é porque, de certeza, falta um "GROUP BY".
Ai vai um exemplo que não usa sequer DataEnvironment é tudo feito por código, mas para o efeito, serve perfeitamente.
Public Sub EmiteGuia()
Set cmdGUIA_REMESSAcab = New Command
Set cmdGUIA_REMESSAcab.ActiveConnection = db
'Recordset hierárquica para a construção do Report (Guia de Remessa)
cmdGUIA_REMESSAcab.CommandText = "SHAPE {SELECT tMOVIMENTOS.codigo AS coddist," & _
"tENTIDADES.ent_nome AS dist,tENTIDADES.ent_morada AS distmorada, tENTIDADES.ent_local AS distlocal, " & _
"tENTIDADES.cpos_codig AS distcpost, tENTIDADES.cpost_desig AS distcpostdesig, tENTIDADES.cpos_codig1 AS discpost1," & _
"tENTIDADES.ent_tel AS disttel, tENTIDADES.ent_fax AS distfax, tMOVIMENTOS.ent_num AS coddest, tENTIDADES1.ent_nome AS dest," & _
"tENTIDADES1.ent_morada AS destmorada, tENTIDADES1.ent_local AS destlocal, tENTIDADES1.cpos_codig AS destcpost," & _
"tENTIDADES1.cpos_codig1 AS destcpost1, tENTIDADES1.cpost_desig AS destcpostdesig, tENTIDADES1.ent_num_contr AS destnumcontr," & _
"mid(tMOVIMENTOS.mov_docref, 5, 10) AS guia_num, tMOVIMENTOS.mov_tipo, tMOVIMENTOS.id_movimento, tMOVIMENTOS.data AS Data,sum(tMOVIMENTOSdet.valor) as total " & _
"FROM tENTIDADES, tMOVIMENTOS, tENTIDADES tENTIDADES1, tMOVIMENTOSdet " & _
"WHERE tENTIDADES.ent_num = tMOVIMENTOS.codigo AND tMOVIMENTOS.ent_num = tENTIDADES1.ent_num AND tMOVIMENTOS.codigo = tMOVIMENTOSdet.codigo " & _
"AND tMOVIMENTOS.id_movimento = tMOVIMENTOSdet.id_movimento " & _
"GROUP BY tMOVIMENTOS.codigo, tENTIDADES.ent_nome, tENTIDADES.ent_morada, tENTIDADES.ent_local, tENTIDADES.cpos_codig, tENTIDADES.cpost_desig," & _
"tENTIDADES.cpos_codig1, tENTIDADES.ent_tel, tENTIDADES.ent_fax, tMOVIMENTOS.ent_num, tENTIDADES1.ent_nome, tENTIDADES1.ent_morada," & _
"tENTIDADES1.ent_local, tENTIDADES1.cpos_codig, tENTIDADES1.cpos_codig1, tENTIDADES1.cpost_desig, tENTIDADES1.ent_num_contr, mid(tMOVIMENTOS.mov_docref, 5, 10)," & _
"tMOVIMENTOS.mov_tipo , tMOVIMENTOS.id_movimento, tMOVIMENTOS.Data " & _
" HAVING (tMOVIMENTOS.codigo =" & cod & ") AND (tMOVIMENTOS.id_movimento = '" & id & "')} AS qGUIA_REMESSAcab " & _
"APPEND ({SELECT tARTIGOS.art_desig AS artigo, tMOVIMENTOSdet.art_quant AS quantidade, tMOVIMENTOSdet.art_valunit AS valor," & _
"tMOVIMENTOSdet.serie_fim AS final, tMOVIMENTOSdet.serie_id AS serie, tMOVIMENTOSdet.serie_ini AS inicio, tMOVIMENTOSdet.valor AS total," & _
"tMOVIMENTOS.id_movimento, tMOVIMENTOS.codigo FROM tARTIGOS, tMOVIMENTOSdet, tMOVIMENTOS WHERE tARTIGOS.art_codig = tMOVIMENTOSdet.art_codig " & _
"AND tMOVIMENTOSdet.codigo = tMOVIMENTOS.codigo AND tMOVIMENTOSdet.id_movimento = tMOVIMENTOS.id_movimento " & _
"GROUP BY tARTIGOS.art_desig," & _
"tMOVIMENTOSdet.art_quant , tMOVIMENTOSdet.art_valunit, tMOVIMENTOSdet.serie_fim, tMOVIMENTOSdet.serie_id,tMOVIMENTOSdet.serie_ini," & _
"tMOVIMENTOSdet.valor, tMOVIMENTOS.id_movimento, tMOVIMENTOS.codigo} AS qGUIA_REMESSAdet RELATE 'id_movimento' TO 'id_movimento','coddist' TO 'codigo') AS qGUIA_REMESSAdet "
Set adoGUIA_REMESSAcab = cmdGUIA_REMESSAcab.Execute
Dim intCtrl As Integer
With rptGUIA_REMESSA
Set .DataSource = adoGUIA_REMESSAcab
With .Sections("Section1").Controls
For intCtrl = 1 To .Count
If TypeOf .Item(intCtrl) Is RptTextBox Then
.Item(intCtrl).DataMember = "qguia_remessadet"
End If
Next intCtrl
End With
With .Sections("Section7").Controls
For intCtrl = 1 To .Count
If TypeOf .Item(intCtrl) Is RptTextBox Then
.Item(intCtrl).DataMember = ""
End If
If TypeOf .Item(intCtrl) Is RptFunction Then
.Item(intCtrl).DataMember = "qguia_remessadet"
End If
Next intCtrl
End With
.Orientation = rptOrientPortrait
.PrintReport
Set adoGUIA_REMESSAup = New Recordset
db.CursorLocation = adUseClient
Set cmdGUIA_REMESSAup = New Command
Set cmdGUIA_REMESSAup.ActiveConnection = db
'actualiza a tabela das Guias de Remessa
cmdGUIA_REMESSAup.CommandText = "INSERT INTO tGUIA_REMESSA " & _
"(guia_num,codigo,ent_num, data, marca_guia)" & _
"SELECT mid(mov_docref, 5, 10)AS guia_num, codigo, ent_num,data,'E' AS marca_guia " & _
"From tMOVIMENTOS " & _
"where tMOVIMENTOS.codigo = " & cod & " " & _
" and tMOVIMENTOS.id_movimento = '" & id & "'"
Set adoGUIA_REMESSAup = cmdGUIA_REMESSAup.Execute
End With
End Sub
De qualquer forma, se quizer ver um exemplo prático, dê uma olhada:
João Mateus