• Privacywetgeving
    Het is bij Helpmij.nl niet toegestaan om persoonsgegevens in een voorbeeld te plaatsen. Alle voorbeelden die persoonsgegevens bevatten zullen zonder opgaaf van reden verwijderd worden. In de vraag zal specifiek vermeld moeten worden dat het om fictieve namen gaat.

Gegevens ophalen m.b.v. een macro

Status
Niet open voor verdere reacties.

McMacro

Gebruiker
Lid geworden
11 dec 2009
Berichten
80
Beste Excellers ;),

Ik heb Excelbestand A en Excelbestand B.
  • In A staan in 67 kolommen (A:BQ) gegevens onder elkaar in een als maar langer wordende lijst. Rij 1 staan kolomkoppen, vanaf rij 2 de lijst.
  • In B staan in 28 kolommen (A:AB) gegevens onder elkaar in een lijst met gegevens van 13 kolommen uit bestand A.

Het gaat dan met name om klant/persoonsgegevens, die in principe iedere keer opnieuw ingevoerd moeten worden. Ik zou dit graag uit bestand A willen ophalen. Die gegevens zijn aan een document/dossiernummer (col 6 of F) en datum (col 67 of BO) gebonden.

Inprincipe zou ik graag willen dat hij de meest recente datum zoekt in bestand B, bijvoorbeeld: 15-12-2010, dan moet hij in bestand A verder zoeken vanaf 16-12-2010 gekoppeld aan een uniek ducument/dossiernummer (zodat er geen dubbele voorkomen maar beslist ook niet te weinig rijen opgehaald worden uit bestand A, want op één dag kunnen er meerdere dossiers aangemaakt worden, die allen naar bestand B moeten).

Pfff... Dat was het wel weer. Kunnen jullie het nog volgen? Vragen zijn welkom! :D

Met vriendelijke groet,

McMacro
 
Ik probeer:confused: wat meer toelichting te geven:

Code in bestand B:
Code:
Sub UpdateLijst()
Application.ScreenUpdating = False
 Sheets(1).Unprotect

    Sheets(1).Range("A5:AB1500").Sort _
     Key1:=Range("D5"), Order1:=xlDescending, _
     Key2:=Range("C5"), Order2:=xlDescending, _
        Header:=xlNo, _
        Ordercustom:=1, _
        MatchCase:=False, _
        Orientation:=xlTopToBottom
    ActiveWindow.ScrollRow = 1
 Sheets(1).Protect
Application.ScreenUpdating = True
End Sub

Nadat de lijst in Sheets(1) sorteerd is, staat in cel C5 een uniek dossiernummer en in cel D5 de meest recente datum.

In principe zou de formule/vbacode zich kunnen richten op de deze 2 cellen?!

Dan kan in het andere bestand A ook alles sorteerd worden en gezocht naar de meest recente datum die we in bestand B hadden staan in C5 en D5. En alles (alleen de specifieke kolommen) vanaf daar tot boven moet dan gekopieerd worden naar bestand B, zodat die lijst ook uptodate is met de laatste gegevens.

Hopelijk kunnen jullie er iets mee?

Met vriendelijke groet,

McMacro



PS. Ik werk met Excel 2000
 
Laatst bewerkt:
Kan je geen voorbeeldbestandje toevoegen?
Maak kopieën van je bestanden en zet er dummy-waarden in, zodat we kunnen zien wat en hoe.

Cobbe
 
Laatst bewerkt:
Wat moet het resultaat zijn?
Alle rijen die nieuwer zijn dan de laatste datum uit bestand 1 moeten in bestand 2 gekopieerd worden. Maar niet hele rijen, alleen een aantal bepaalde cellen uit de rij die een eigen plaats krijgen.

Wat moet er gebeuren?
- Zoek in bestand 1 de meest recente datum in column(4) (of gewoon kolom D).
- Ga met dat gegeven naar bestand 2 en zoek in column(67) (of gewoon kolom BO) naar deze datum en kopieer alle data die recenter is dan de datum uit het zoekresultaat.
- Vervolgens kopieer alleen die cellen uit de rij die nodig zijn in bestand 1. (bijvoorbeeld: datum uit column(67) uit bestand 2 moet op de plaats van column(4) in bestand 1 komen te staan.
- Dat moet zo verder tot dat er geen cel en rij meer over is.
- Handig zou zijn dat de zoekfunctie ook de datum relateerd aan een dossiernummer. De combinatie daten en dossiernummer is uniek. Alleen de datum niet, die is niet uniek want deze kan ook 5 keer voorkomen als er meerdere dossiers op dezelfde dag aangemaakt worden.

Voorbeeld:
In bestand 1 is de meest recente datum: 01-12-2010 (gevonden door dat deel van de macro)
(... Macro opent bestand 2 en zoekt naar de meest recente datum uit bestand 1)
Nadat de meest recente datum van bestand 1 gevonden is, dienen alle nieuwere dossiers (*lees: bepaalde cellen van de gevonden rijen) gekopieerd te worden naar bestand 1.
Als alles overgebracht is naar bestand 1, dient bestand 2 afgesloten te worden.

NB.
Als er geen recentere datum gevonden wordt (doordat bijvoorbeeld per ongeluk 2x op de knop geklikt geworden is, dient er een msgbox te verschijnen dat er geen nieuwere data/dossiers zijn).


Misschien is dit iets duidelijker?

Met vriendelijke groet,



Mc Macro

Zie deze dummy als voorbeeld:
 
Laatst bewerkt:
zet even een bestandje neer met in dezelfde map maar op 2 verschillende werkbladen wat er in je bestand A en bestand B staat, dus de koprijen en daarna 10 regels gegevens (zonder gevoelige info). Dat werkt sneller dan 1.000 woorden.
 
Bedankt voor de tip!

Hier is het bestand zoals Cow18 aangaf het op te zetten.

Hopelijk hebben jullie hier meer aan.

Met vriendelijke groet,



McMacro
 
Laatst bewerkt:
soms verdenk de je TS soms van een beetje pleinvrees om hun gegevens te tonen, ik heb zelf wat dummy-gegevens erin gestopt en vermoed dat het goed is, maar bij gebreke aan echte data kan er natuurlijk in mijn gedachtengang tov jouw gegevens altijd een afwijking zitten !!!
In Blad1 staat een belangrijke tabel om het verband tussen de kolommen te kennen.
De rest is wat knip en plakwerk.
Als het met 2 werkbladen binnen 1 bestand lukt, dan is de aanpassing naar 2 verschillende werkmappen eigenlijk nog peanuts.
 

Bijlagen

Beste Cow18,

Ten eerste, heel erg bedankt voor de moeite. Hier zou ik niet op gekomen zijn.
Klopt de instelling van Set sh2 = ... (zie hieronder)

Code:
Option Explicit

Sub Update1to1()
  Dim Recentste As Date, Dossier As String, c1 As Range, c2 As Range, lrij As Long, s As String, i As Integer, Kolommen As Variant, splits As Variant, Waarde As Variant
  Dim sh1 As Worksheet, sh2 As Worksheet, Bereik As Range
  Set sh1 = Sheets("Bestand1")                              'doel
  Set sh2 = Workbooks.Open("C:\Mijn Documenten\Testomgeving\Bestand2.xls").Sheets(1)
  [COLOR="red"]Kolommen = Range("CorKolNr")[/COLOR]  [COLOR="seagreen"]'Hier krijg ik de volgende melding: Fout 1004 tijdens uitvoering: Methode Range van object_Global is mislukt[/COLOR]
...[rest van de code]

Net als in jouw aangepaste bestand heb ik op blad2 van bestand1 (doelbestand) een range/bereik aangemaakt met de naam "CorKolNr".
Wat gaat er verkeerd?
 
Laatst bewerkt:
Als in Bestand2 recentere datums bevat samen met nieuwe dossiernummers dan in Bestand1 (doelbestand)... geeft de macro toch aan dat er recent geen nieuwe dossiers toegevoegd zijn?! Voor de rest zijn er geen 'foutmelding(en)' meer.

Enig idee waaraan dat kan liggen? Even ter herinnering ik gebruik Excel2000.

Code:
Option Explicit

Sub Update1to1()
  Dim Recentste As Date, Dossier As String, c1 As Range, c2 As Range, lrij As Long, s As String, i As Integer, Kolommen As Variant, splits As Variant, Waarde As Variant
  Dim sh1 As Worksheet, sh2 As Worksheet, Bereik As Range
  Set sh1 = Sheets(1)                              'doel
  Set sh2 = Workbooks.Open("C:\Mijn Documenten\Testomgeving\Bestand2.xls").Sheets(1) 'bron
  Kolommen = [COLOR="green"]Array[/COLOR]("CorKolNr")  'lees in een array alle overeenkomstige kolommen in tussen beide bestanden
  Recentste = WorksheetFunction.Max(sh1.UsedRange.Columns(4).Offset(4)) 'recentste datum in Bestand1.Sheet(1)
  With sh2
    .AutoFilterMode = False
    .UsedRange.Columns(67).AutoFilter 1, ">=" & CLng(Recentste)  'alle rijen met een datum >= recentste datum
    Set Bereik = .UsedRange.Columns(67).SpecialCells(xlVisible)  'alle gefilterde cellen
    If WorksheetFunction.CountA(Bereik) = 1 Then MsgBox "Dit waren alle recente dossiers.": Exit Sub  'maar 1 rij over = stoppen
    For Each c2 In Bereik.SpecialCells(xlConstants)              'alle niet-lege zichtbare cellen aflopen
      lrij = c2.Row                                              'rijnummer in doelbestand
      If lrij > 1 Then
        Dossier = .Cells(lrij, 6).Value                          'dossiernaam
        Set c1 = Nothing: Set c1 = sh1.Columns("C").Find(Dossier, lookat:=xlWhole)  'zoek dossier op in kolom C van doel
        If c1 Is Nothing Or c2.Value > Recentste Then            'niet gevonden = toevoegen of datum groter dan recentste = toevoegen
          For i = 1 To UBound(Kolommen)                          'loop alle te kopieren cellen af
            Select Case i                                        'afhankelijk van te kopieren cel
              Case 1: Waarde = IIf(IsEmpty(sh2.Cells(lrij, Kolommen(i, 2)).Value), "???", sh2.Cells(lrij, Kolommen(i, 2)).Value)  'dossier mag zeker niet leeg zijn
              Case 2: Waarde = CLng(sh2.Cells(lrij, Kolommen(i, 2)).Value)  'datum wegschrijven als long
              Case Else: Waarde = sh2.Cells(lrij, Kolommen(i, 2)).Value     'al de rest doet er niet toe
            End Select
            s = s & Waarde & IIf(i = UBound(Kolommen), vbLf, vbTab)  'verzamelstring met gepaste separator
          Next
        End If
      End If
    Next
    .AutoFilterMode = False
  End With

  If s = "" Then MsgBox " Er zijn recent geen nieuwe dossiers toegevoegd!": Exit Sub  'verzamelstring is leeg = stoppen
  splits = Split(s, vbLf)                                  'splits verzamelstring op de vblf
  With sh1                                                 'in doelcel
    With Range("C" & Rows.Count).End(xlUp).Offset(1).Resize(UBound(splits))  'kopieer in gebied onder laatste niet-lege C-cel
      Application.Goto .Range("A1"), False                 'ga op 1e nieuw toegevoegde dossier staan
      .Value = WorksheetFunction.Transpose(splits)         'voeg knipsels toe
      Application.DisplayAlerts = False
      .TextToColumns Tab:=True                             'knip knipsels verder in stukken op de vbtab
      Application.DisplayAlerts = True
    End With
  End With
End Sub

Verder zou het praktisch zijn dat Bestand2 (bronbestand) ook weer geloten wordt. Op welke verschillende plaatsen moet de opdracht '.close' geplaatst worden?

Met vriendelijke groet,

McMacro
 
dat tabelletje in blad1 staat in je eerste bestand en is nu zonder gedefinieerde naam maar als hard adres beschreven in de macro
het 2e bestand dat je wenst te openen staat bovenin als een variabele in je module
verder wordt er gekeken of je 2e bestand nog niet open is, zoniet wordt het geopend en later weer gesloten (als het niet open was bij het begin) zonder opslaan.
Verder staat daar nu een msgbox in voor het testen, die mag later verdwijnen.
Mijn vermoeden is dat de array kolommen geen gegevens bevatte en daarom niets werd weggeschreven.

Code:
Option Explicit
[COLOR="red"]Const Bestand2 As String = "C:\Mijn Documenten\Testomgeving\Bestand2.xls" 'voor McMac[/COLOR]ro
'Const Bestand2 As String = "C:\data\Excell\Forum\Bestand2.xls"  'voor Bart

Sub KopierenVan1Naar2()
  Dim Recentste As Date, Dossier As String, c1 As Range, c2 As Range, lrij As Long, s As String, i As Integer, Kolommen As Variant, splits As Variant, Waarde As Variant
  Dim Sh1 As Worksheet, Sh2 As Worksheet, Bereik As Range, TB1 As Workbook, WB2 As Workbook, bOpen As Boolean

  Set TB1 = ThisWorkbook
  Set Sh1 = TB1.Sheets("Bestand1")                         'doel
  [COLOR="red"]Kolommen = TB1.Sheets("blad1").Range("B2:C14")  [/COLOR]'lees in een array alle overeenkomstige kolommen in tussen beide bestanden, STAAT IN THISWORKBOOK IN BLAD1 !!!!!!!
  If UBound(Kolommen) < 1 Then MsgBox "je hebt niets gevonden over je kolommen": Exit Sub
  Recentste = WorksheetFunction.Max(Sh1.UsedRange.Columns(4).Offset(4))  'recentste datum in bestand1

  splits = Split(Bestand2, "\")                            'knip verwijzing naar je 2e bestand in stukjes op "\"
  On Error Resume Next
  Set WB2 = Workbooks(splits(UBound(splits)))              'probeer de map met die filename (zonder path) aan te spreken
  bOpen = Not (WB2 Is Nothing)                             'onthouden voor straks dat WB2 open staat
  If Not bOpen Then
    Set Sh2 = Workbooks.Open(Bestand2)
    Set WB2 = Workbooks(splits(UBound(splits)))            'probeer de map met die filename (zonder path) aan te spreken
    If WB2 Is Nothing Then MsgBox " het bestand " & Bestand2 & " is niet te openen !!!!": Exit Sub
  End If
  Set Sh2 = WB2.Sheets(1)                                  '                           'bron
  MsgBox "kloppen onderstaande gegevens" & vbLf & "Deze map " & vbTab & TB1.Name & vbLf & "2e map " & vbTab & WB2.Name & vbLf & "Recentste datum " & vbTab & Format(Recentste, "dd-mm-yyyy") & vbLf & "aantal rijen in je tabel " & vbTab & UBound(Kolommen) & vbLf & "laatste gegevens in kolommen " & vbTab & Kolommen(UBound(Kolommen), 1) & vbTab & Kolommen(UBound(Kolommen), 2)
  With Sh2
    .AutoFilterMode = False
    .UsedRange.Columns(67).AutoFilter 1, ">=" & CLng(Recentste)  'alle rijen met een datum >= recentste datum
    Set Bereik = .UsedRange.Columns(67).SpecialCells(xlVisible)  'alle gefilterde cellen
    If WorksheetFunction.CountA(Bereik) = 1 Then MsgBox "geen recente dossiers meer": Exit Sub  'maar 1 rij over = stoppen
    For Each c2 In Bereik.SpecialCells(xlConstants)        'alle niet-lege zichtbare cellen aflopen
      lrij = c2.Row                                        'rijnummer in doelbestand
      If lrij > 1 Then
        Dossier = .Cells(lrij, 6).Value                    'dossiernaam
        Set c1 = Nothing: Set c1 = Sh1.Columns("C").Find(Dossier, lookat:=xlWhole)  'zoek dossier op in kolom C van doel
        If c1 Is Nothing Or c2.Value > Recentste Then      'niet gevonden = toevoegen of datum groter dan recentste = toevoegen
          For i = 1 To UBound(Kolommen)                    'loop alle te kopieren cellen af
            Select Case i                                  'afhankelijk van te kopieren cel
              Case 1: Waarde = IIf(IsEmpty(Sh2.Cells(lrij, Kolommen(i, 2)).Value), "???", Sh2.Cells(lrij, Kolommen(i, 2)).Value)  'dossier mag zeker niet leeg zijn
              Case 2: Waarde = CLng(Sh2.Cells(lrij, Kolommen(i, 2)).Value)  'datum wegschrijven als long
              Case Else: Waarde = Sh2.Cells(lrij, Kolommen(i, 2)).Value  ' al de rest doet er niet toe
            End Select
            s = s & Waarde & IIf(i = UBound(Kolommen), vbLf, vbTab)  'verzamelstring met gepaste separator
          Next
        End If
      End If
    Next
    .AutoFilterMode = False
  End With
  If Not bOpen Then WB2.Close xlNo                         'was WB2 niet open, sluit hem hier zonder opslaan

  If s = "" Then MsgBox " er werden geen nieuwe dossiers toegevoegd": Exit Sub  'verzamelstring is leeg = stoppen
  splits = Split(s, vbLf)                                  'splits verzamelstring op de vblf
  With Sh1                                                 'in doelcel
    With Range("C" & Rows.Count).End(xlUp).Offset(1).Resize(UBound(splits))  'kopieer in gebied onder laatste niet-lege C-cel
      Application.Goto .Range("A1"), False                 'ga op 1e nieuw toegevoegde dossier staan
      .Value = WorksheetFunction.Transpose(splits)         'voeg knipsels toe
      Application.DisplayAlerts = False
      .TextToColumns Tab:=True                             'knip knipsels verder in stukken op de vbtab
      Application.DisplayAlerts = True
    End With
  End With
End Sub
 
Bedankt

Bedankt Cow18!!!

De Macro werkt super! Helemaal zoals ik gehoopt had dat het zou werken.
Echter nu blijkt dat toch Bestand2 niet altijd even correct gevuld wordt.
Dus... Het dossier/rij wordt wel aangemaakt... met een bijhorend dossiernummer, maar de verzenddatum wordt later ingevoerd. Omdat verschillende mensen Bestand2 vullen kan het zijn dat iemand een oudere datum invoerd dan 'Recentste' uit de macro. Die worden dan niet meegenomen.

Mijn vraag is... of de Macro kunnen laten zoeken naar de unieke dossiernummers en hun datum, zodat allen die nog niet aan Bestand1 toegevoegd waren, nu toegevoegd worden.

Is dit mogelijk?

Met vriendleijke groet,

McMacro
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan