< návrat zpět

MS Excel


Téma: Porovnání dvou polí - VBA rss

Zaslal/a 5.9.2017 13:48

Zdravím,

mám prosím takvý dotaz:

mám dvě dynamické pole (Day1 a Day2). V jednom poli je uloženo 6 jmen a v jednom 5 jmen. Potřebuji, abych mohl tyto dvě pole porovnat a aby výstup byl takový:

Program vypíše, jaké jméno je v Day1 ale není v Day2 a zároveň číslovkou napíše, o kolik takových jmen se jedná (v našem případě to je logicky 1).

Později bude tento sysém aplikovaný na mnohem více jmen. Takže potřebuji aby to bylo vyřešeno makrem.

Za rady moc díky :)

Zaslat odpověď >

Strana:  « předchozí  1 2 3 4 5   další »
#037549
elninoslov
Heh, kód je HardCore kvôli ošetrovaniu rôznych eventualít:
-čo ak nie sú zadané mená v jednom či druhom poli (vtedy stačí skopírovať opačné)
-alebo nie sú v oboch (vtedy sa nerobí nič)
-sú nejaké starý výsledky na zmazanie (pre obe polia) ?
-samozrejme musí byť kontrolovaný zápis každého poľa, či vôbec existuje...

kontroly eventuálnych chýb to nabobtnajú najviac
uvidím podľa času a chuti, možno Vám prekopen aj iný variant...

EDIT: Pozor, v mojom predošlom príspevku som našiel chybku. Príloha je tam vymenená.citovat
icon #037550
eLCHa
@David123
Jakou máte verzi excelu. Tohle totiž úplně jednoduše zvládne Power query (Sloučit dotazy a použít Levé Anti)

Jinak, komentáře nepíšu. On je to jednoduchý kód a nejlépe to stejně pochopíte, když na to přijdete sám (jé, tohle dělá tohle, ahá...)citovat
#037552
avatar
elninoslov:

chybku jsem si opravil. Ale stále mi nefunguje situace, kdy v Day2 mám vložené pouze jedno jméno a nebo v day1 mám jenom jedno jméno. Třeba mám

Day1 Day2
David Lukáš
Lenka

a hodí to chybu. Koukl bys prosím na to? Díky :-)

eLCHa:

Verzi mám 2016. Potřebuji to ale udělat přes makra. Tento krok co jsem řešil dneska je jenom jedním z nekolika kroků, které budu muset spojit dohromady. Ve výsledku budu porovnávat soubory kde jeden má 17000 řádků. Některé mají 20000. Zároveň se s VBA učím. Udělal jsem si některé kroky sám. Ty jednodušší. Ty těžší (pro mě) jsem řešil zde na foru. Prostuduju si je a zase budu chytřejší. Nemusím makra ovládat nějak extra dobře. Až udělám toto, zase to dlouhou dobu neuvidím.citovat
#037555
elninoslov
Opravené v príspevku s prílohou, bola tam ešte jedna chyba, ktorá vznikla premenovávaním mojich názvov polí na Vaše (D1 vs. Day1). To len potvrdzuje to, že samotné porovnanie je pár riadkov, ale desiatky sú kontrola rôznych nechcených stavov.

Keď ale píšete, že až 17K vs. 20K riadkov, tak Vám snáď ešte urobím tú, čo to robí cez reťazec, tá bude možno najrýchlejšia. A možno to aj otestujem 1

EDIT: No teraz keď je tam už toľko podmienok, ošetrujúcich všakovaké možné stavy a ich kombinácie, už sa mi to veru nepáči. Postupne ako to človek ladí, prichádzajú stále nové a nové komplikácie, až sa Vám nakoniec znepáči samotný návrh. Sú tam opakujúce sa časti pre obe polia, tak by sa to dalo spracovať procedúrou s parametrami, bolo by to snáď kratšie. Uvidím, ako večer dopadne 2. verzia.citovat
#037567
avatar
Ahoj elninoslov,

procházím a krokuju si program od tebe, ale je zde pár příkazů u kterých tápu. Začnu od začátku:

1)Day1 = .Cells(2, 1).Resize(R1).Value2 'načtení jmen do pole Day1

píšeš v komentu, že příkaz slouží pro načtení jmen do pole Day1. Když si ale provedu krokování, tak když mám v R1 třeba 5 (5 jmen) tak v Day1 je hodnota Empty. navíc jsem podle google pochopil (možná špatně), že Resize slouží pro rozšíření oblasti. Nikoliv pro načtení dat. Co teda přesně prosím dělá příkaz? Nějak nahrazuje cyklus For pro načtení jmen do Day1?

Day1 = .Cells(2, 1).Resize(R1).Value2

Díky.citovat
#037569
elninoslov
Včera som sa k ďalšiemu variantu nedostal.
Keď ste ešte len na riadku
Day1 = .Cells(2, 1).Resize(R1).Value2
tak pole nieje naplnené, len je vytvorené, teda má veľkosť
riadky 1-5
stĺpce 1-1

každá hodnota je Empty (prázdna hodnota)
keď dáte ešte raz F8 a prejdete na ďalší riadok, až potom sa riadok vykoná a pole dostane hodnoty z patričných buniek. Ožltnutý riadok v kóde pri krokovaní je len označenie riadka, ktorý sa bude najbližšie vykonávať, nieje ešte vykonaný.

Tých podmienok je tam preto toľko, lebo ak je napr meno iba jedno, tak ho Excel do VBA nevráti ako pole 1x1 ale ako jednu hodnotu. Ďalej napr. ak jedno pole je prázdne, tak je zbytočná kontrola, lebo to znamená, že všetky z neprázdneho v prázdnom chýbajú, tak sa iba skopírujú, samozrejme iba v prípade, že nieje prázdne aj jedno aj druhé, a samozrejme s ošetrením ak by to nebolo pole ale iba jedna hodnota (viď vyššie), a kombinácie týchto podmienok. Skoro to isté vypodmienkovanie stavov platí aj pri následnom zápise. A tým sa stáva kód dlhý, a čo je dlhé, je zložité, a čo je zložité je náchylné k chybám.
...

PS: Inak vidíte našiel ste ďalšiu nepresnosť v poznámke:
Day1 = .Cells(2, 1).Resize(R1).Value2 'načítanie mien do poľa Day2
a
Day2 = .Cells(2, 4).Resize(R2).Value2 'načítanie mien do poľa Day2
majú rovnaký popisok, ale samozrejme pri kopírovaní riadkov kde sa mení iba R1 na R2 a Day1 na Day2 som zabudol zmeniť popisok na
'načítanie mien do poľa Day1
v prvom prípade.

EDIT: Inak pre programátora je jedna z najťažších vecí ošetriť všetky možné veci, čo dokáže užívateľ vo svojej vynaliezavosti vyparatiť. Nadáva sa tomu blbuvzdornosť. A je to začarovaný kruh. Preto aj často veľmi zložité veci, ako napr. Windows, majú veľa chýb, lebo ich univerzálnosť tlačí pred sebou nepredstaviteľnú komplikovanosť, previazanosť, závislosť a robustnosť kódov. Vývojári nemajú šancu, ešte že majú užívateľov, ktorý ich upozornia (niekedy aj pár rokov v kuse). 1citovat
#037570
avatar
promin, ale jsem pořád z toho plnění polí Day1 a Day2 zmatený. Myslel jsem, že aby se pole naplnilo nějakými daty z vybrané oblasti, je k tomu potřeba použít nějaký cyklus. V tvém kódu se ale cyklus nevykytuje a příkaz je okomentovany tak, že již pole bylo naplněno. Jaký příkaz prosím přesně pole naplní? A když jsou obě dvě pole plné, jsou plné jmény z vybrané oblasti, ne? Ne pouze číslovkou, kolik jmen v oblasti je. Díky za objasnění :)

If R1 <> 0 Then
ReDim Day1(1 To R1, 1 To 1) 'příprava pole jmen Day1 podle množství prvků
If R1 = 1 Then
Day1(1, 1) = .Cells(2, 1).Value2 'načtení jmen do pole Day1, když je pouze jedno jméno
Else
Day1 = .Cells(2, 1).Resize(R1).Value2 'načtení jmen do pole Day1
End If
End If
If R2 <> 0 Then
ReDim Day2(1 To R2, 1 To 1) 'příprava pole jmen Day2 podle množství prvků
If R2 = 1 Then
Day2(1, 1) = .Cells(2, 4).Value2 'načtení jmen do pole Day2, když je pouze jedno jméno
Else
Day2 = .Cells(2, 4).Resize(R2).Value2 'načtení jmen do pole Day2
End If
End If
citovat
#037571
Stalker
Ahoj Pole není nutné plnit postupně cyklem, ale je možné naplnit ho "hromadně". Udělal sem video, kde sem doplnil kód o funkci select jen z toho důvodu, aby bylo vidět co se děje na listu. Koukni co se děje na listu a v okně Locals v editoru VBA.

Ještě odkaz na video
http://leteckaposta.cz/902336012citovat
#037574
avatar
Ahoj stalker,

Diky moc za super video. Zapl jsem si i Local list. Presne něco takového jsem hledal. Ale nevedel jestli to tam je.

Diky :)citovat
#037575
avatar
Stalker:

chápu nyní, že se pole naplní hromadně, bez nutnosti cyklu. Toto naplnění způsobí funkce Resize?
Sub test_pole()

Dim pole()
Dim x As Integer
Dim Data_count As Integer

i = Rows.Count

Data_count = ThisWorkbook.Worksheets("List1").Cells(i, 1).End(xlUp).Row

'ThisWorkbook.Worksheets("List1").Range(Cells(1, 1), Cells(Data_count, 1)).Copy

ReDim pole(1 To Data_count)

pole = ThisWorkbook.Worksheets("List1").Cells(1, 1).Resize(Data_count).Value2


Nyní je v "pole" uložené vše, so začíná A1 a končí Data_count. Proč ale? Co přesně toto zařídilo?

A ještě prosím dotaz.

Když by si chtěl data co jsou v poli "pole" vypsat pod sebe do sloupce. Jak by si to udělal?

Díkycitovat

Strana:  « předchozí  1 2 3 4 5   další »

Uživatelské menu

Nejste přihlášen(a)
avatar\n

Menu

Formulář Faktura

Formulář Faktura IV

Oblíbený formulář Faktura byl vylepšen a rozšířen.
Více se dočtete zde.

Helios iNuvio

Používáte podnikový systém Helios iNuvio? Potřebujete pomoci se správou nebo vyvinout SQL proceduru? Více informací naleznete na stránce Helios iNuvio.

On-line nástroje