vbamania.pl
login:
hasło:
 
  *Rejestracja *Zapomniane hasło
 Dziś jest sobota, 18 maja 2024 roku.
Ustaw jako stronę startową Ulubione Napisz
PowrótPowrót do serwisu  RegulaminRegulamin rssRSS

  tytuł wątku:
Wątki dyskusji

Jak pobierać wybraną dowolnie ilość ostatnich niepowtarzalnych danych z kolumny arkusza Excela i rejestrować je w tabeli innego arkusza? Prośba o pomoc.


otwartyotwarty rozpoczął: Ala postów: 18



napisał: Trebor
postów: 1209


umieszczony:
30 października 2010
09:52

edytowany:
30 października 2010
09:55

  
Co do murarza to nie tak
If tbla(1, j) = kol(i) Then tbla1(j) = 1
Next i
If tbla1(j) = "" Then tbla1(j) = 0


Pierwsze murarz sprawdza czy unikat znajduje się we wskazanym wierszu i jeśli tak to przypisuje jedynkę (chwilowo w tablicy). Po przejściu pętli sprawdza czy jedynka została przypisana, jeśli nie przypisuje 0. Na końcu wstawia dane. W ten sposób nie ma konieczności wcześniejszego czyszczenia zakresu. Tą pętlę łatwo przyśpieszyć, ale do tego jeszcze dojdziesz.
Jeśli coś nie działa może to oznaczać, że nasz układ danych jest różny.

Hej
napisał: Ala
postów: 16


umieszczony:
30 października 2010
07:11

edytowany:
30 października 2010
07:27

  
Za ogromną pomoc i wyrozumiałość i okazaną cierpliwość bardzo dziękuję Kolegom: Adminowi, Treborowi i Ml.

Program Kol. Trebora wygląda znakomicie, jest niebywale zwięzły i zdumiewająco szybki.

Ta szybkość, jak wynika z literatury, prawdopodobnie jest wynikiem zastosowania szybkich pętli typu
With
End With

Teraz czeka mnie zakup jakiegoś dobrego podręcznika, bo te trzy które mam są niestety zbyt mało zaawansowane.

Dalej spróbuję dopracować makro kol. Trebora sama, wpierając się pomysłami Kolegów Admina i Ml oraz podręcznikami,
bo nie śmiem już dłużej się Kolegom narzucać..

Biorę miesiąc urlopu i zrobię następujące rzeczy w programie Kol. Trebora:

1) Zmodyfikuję kod w taki sposób, aby kod w podprogramie NAJPIERW ZEROWAŁ TABELE A DOPIERO POTEM JE ZAPEŁNIAŁ. Bo wynikła dość zabawna niedogodność, TERAZ jest jak murarz, który idzie do pracy i najpierw buduje mur a następnie go burzy i idzie do domu. Ma być na odwrót. Obecnie w wyniku tej niedogodności efektem po obliczeniach są ZAWSZE same zera w tabeli.

2) Spróbuję jakoś zrobić, żeby można było do kodu wpisywać konkretne adresy całych tabel /jako zmienne, czy jako stałe, jeszcze nie wiem/, czyli adres zeszytu, adres arkusza i w arkuszu od numeru wiersza i numery kolumny, do numeru wiersza i numeru kolumny. Tabele są jednowymiarowe, ale mają podwójne nagłówki. Jakoś to w końcu osiągnę! Na szczęście Kol. Admin w sąsiednim wątku podał na moją prośbę jak się to mniej więcej robi. Po prostu podprogram Kol. Trebora potraktuję jako jeden moduł do jednej tabeli wyjściowej. Takich tabel będzie dużo.


3) W jakiś sposób muszę zmienić coś w adresie tabel wyjściowych, aby program wpisywał wyniki dokładnie tam, gdzie chcę, a nie tam, gdzie program chce. Obecnie program wpisuje wyniki wprawdzie we wskazanym wierszu, lecz niestety ZAWSZE zaczyna od pierwszej kolumny. To jest wykluczone, bo te kolumny są już zajęte na inne rzeczy. Tabele mają być i są przesunięte mocno w prawo, poza ekranem.

4) Zbuduję z tych modułów Kol. Trebora program uruchamiany jednym przyciskiem, który będzie przeliczał moduły /czyli tabele/ po kolei, aż przeliczy wszystko.

Bez pomocy Szanownych Kolegów nie byłabym w stanie czegokolwiek z tym zrobić.
Dla początkującego, są to przeszkody nie do pokonania.

Jeszcze raz wyrażam niniejszym ogromną wdzięczność dla Szanownych Kolegów.

Pozdrawiam Szanownych Kolegów
Ala
napisał: Trebor
postów: 1209


umieszczony:
29 października 2010
19:25

  
Materiał do testu:
Sub unikaty()
Dim i As Long, j As Long, tbla, tbla1(), ostatnia As Long, adres As Range, liczba As Integer, kol As New Collection
Dim a As String
On Error Resume Next
Set adres = Application.InputBox("Kliknij na dowolną komórkę w kolumnie z której mają być wyszukane unikaty ", Type:=8)
If adres Is Nothing Then Exit Sub
liczba = Application.InputBox("Podaj ilość unikatów")
On Error GoTo 0
If liczba = 0 Then Exit Sub
With adres.Parent
ostatnia = .Columns(adres.Column).Find(What:="*", After:=.Cells(1, adres.Column), _
               SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
tbla = .Range(.Cells(1, adres.Column), .Cells(ostatnia, adres.Column))
On Error Resume Next
For i = ostatnia To 1 Step -1
kol.Add tbla(i, 1), CStr(tbla(i, 1))
Next i
On Error GoTo 0
If kol.Count < liczba Then liczba = kol.Count
End With
'wyprowadzenie
Set adres = Nothing
On Error Resume Next
Set adres = Application.InputBox("Kliknij na dowolną komórkę w wierszu w której znajdują się kody.", Type:=8)
On Error GoTo 0
If adres Is Nothing Then Exit Sub
With adres.Parent
ostatnia = .Rows(adres.Row).Find(What:="*", After:=.Cells(adres.Row, 1), _
               SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Column
tbla = .Range(.Cells(adres.Row, 1), .Cells(adres.Row, ostatnia))
ReDim tbla1(1 To ostatnia)
For j = 1 To ostatnia
For i = 1 To liczba
a = kol(i)
If tbla(1, j) = kol(i) Then tbla1(j) = 1
Next i
If tbla1(j) = "" Then tbla1(j) = 0
Next j
.Range(.Cells(adres.Row + 1, 1), .Cells(adres.Row + 1, ostatnia)) = tbla1
End With
End Sub

napisał: admin
postów: 613


umieszczony:
29 października 2010
06:08

edytowany:
29 października 2010
06:10

  
Witam,

Wklejenie kilkuset tysięcy wierszy raczej się nie uda, bo forum nie przyjmie takiej ilości danych w oknie tekstowym.
Ale forum ma możliwość załączania plików do postu - nad polem do wpisywania treści postu jest pole wyboru pliku załącznika.
I tutaj kilkaset tysięcy wierszy nie powinno być problemem.
Proszę tylko pamiętać o skompresowaniu pliku (ZIPem albo RARem).
Poza tym admin nie dziękuje tak łatwo użytkownikom za współpracę, bez obaw.

pozdrawiam!



Cytat:
Wklejenie kilkuset tysięcy wierszy raczej nie wchodzi w rachubę, bo Admin mógłby nam wszystkim na tym wątku podziekować na zawsze >

Pozdrawiam
Ala
napisał: Ala
postów: 16


umieszczony:
28 października 2010
21:02

edytowany:
28 października 2010
21:21

  
Trebor

Twoje makro kod jest, jak dla mnie mistrzowsko zwięzłe i wylicza prawidłowo unikalne dane z ostatnich wierszy. W ogóle nie pojmuję, jak można nauczyć się tak ogromnie kolosalnej umiejętności, jak programowanie w VBA i to jeszcze na takim poziomie. To jest miejsce w którym widocznie bywają czarodzieje czyniący cuda.

Kłopot w tym, że niestety makro wpisuje wynik w kolumnie A tej samej z której pobiera dane. Wpisuje wyniki zaczynając od komórki A1.
Jak zrobić, żeby program zapisywał wyniki np. w zeszycie docelowym >>x<<, w arkuszu docelowym >>y<<, w kolumnie docelowej >>kolumn<< ?

Ale to jest dopiero połowa makra o które szło.
Teraz poniżej przedstawiam wymyślony przykład prezentacji danych na wejściu i na wyjściu.

Kod kremów nawilżających Nivea >> 1<<
Kod kremów nawilżających Loreal >>2<<
Kod kremów nawilżających Garnier >>3<<
Kod kremów nawilżających Iwostin >>4<<
Kod kremów nawilżających Vichy >>5<<

Czyli powyżej są kody: pięć unikalnych kodów występujących na wejściu danych. Zakładamy dla uproszczenia, że jest w tej kolumnie danych tylko i wyłącznie tylko 5 różnych kodów.

NA WEJŚCIU:
Przykład ostatnich 15 wierszy powyższej kolumny wejściowej /ostatnie na samym dole kolumny/:
5
5
1
3
3
3
3
2
2
2
2
2
2
2
4

Interesują mnie na przykład 3 ostatnie unikalne kody które wpłynęły, są to: 4, 2, 3.
NA WYJŚCIU:
Gdzieś tam w zeszycie >>x<<, w arkuszu >>y<<, w wierszu zlokalizowanym >>wers<< >> kolumn<< są tabele /u mnie są poziome/.

Np:
KREMY NAWILŻAJĄCE
Kod 1 Kod 2 Kod 3 Kod 4 Kod 5
0 0 0 0 0

Praca makra o które prosiłam powinna spowodować zmianę w odpowiednich komórkach tabeli wyjściowej.
Zmiana w kodach: 4,2,3, czyli tak:
KREMY NAWILŻAJĄCE
Kod 1 Kod 2 Kod 3 Kod 4 Kod 5
0 1 1 1 0

Kolumn wejściowych z dynamicznymi danymi jest wiele i korespondujących tabel na wyjściu ze stałą określoną, różniącą się między sobą lokalizacją odpowiednio tyle samo.
Czyli po wykonaniu całej pracy w tabelach na wyjściu niektóre zera zamieniają się na jedynki.

Przed wykonaniem całości obliczeń we wszystkich kolumnach wejściowych i wszystkich tabelach wyjściowych, powinna być możliwość uprzedniego wyzerowania jedynek w tabelach wyjściowych.

O to mniej więcej chodziło, bo resztę trudności jakoś sama pokonam.
To oczywiście będzie tylko mała część pracy, którą wykonują arkusze. Służą głównie do różnych wyliczeń, bilansów, itp.


P.S. Niestety, skopiowałam tabele z Worda, lecz dane mi się rozsypały. Każdy kod powinien być w komórce w pionie pod swoim nagłówkiem.


Pozdrowienia
Ala
napisał: Ala
postów: 16


umieszczony:
27 października 2010
21:36

edytowany:
28 października 2010
21:34

  
Trebor

Wielkie dzięki za ten makro kod.

Będę to teraz rozgryzała, bo dla mnie VBA to jest kompletna czarna magia i tysiące razy mniej z tego rozumiem, niż Ty z mego postu.

To co na niebiesko rozumiem natychmiast /prosty angielski/. Z tym na czarno na razie jest różnie..

Ale przynajmniej jest nad czym pracować i ten kod oraz kod udostępniony przez kol. Ml powinien w końcu rozwiązać problem.

Jutro odniosę się do makra i zamieszczę jakiś uproszczony przykład danych. Wklejenie kilkuset tysięcy wierszy raczej nie wchodzi w rachubę, bo Admin mógłby nam wszystkim na tym wątku podziekować na zawsze >

Pozdrawiam
Ala
napisał: Trebor
postów: 1209


umieszczony:
27 października 2010
17:37

  
Dużo piszesz, ale bez przykładowych danych trudno to zrozumieć. Poniższe makro wyszukuje unikaty ze wskazanej kolumny.
Sub unikaty()
Dim i As Long, tbla, ostatnia As Long, adres As Range, liczba As Integer, kol As New Collection
Set adres = Application.InputBox("Kliknij na dowolną komórkę w kolumnie z której mają być wyszukane unikaty ", Type:=8)
If adres Is Nothing Then Exit Sub
On Error Resume Next
liczba = Application.InputBox("Podaj ilość unikatów")
On Error GoTo 0
If liczba = 0 Then Exit Sub
With adres.Parent
ostatnia = .Columns(adres.Column).Find(What:="*", After:=.Cells(1, adres.Column), _
               SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
tbla = .Range(.Cells(1, adres.Column), .Cells(ostatnia, adres.Column))
On Error Resume Next
For i = ostatnia To 1 Step -1
kol.Add tbla(i, 1), CStr(tbla(i, 1))
Next i
On Error GoTo 0

If kol.Count < liczba Then liczba = kol.Count
Workbooks.Add
For i = 1 To liczba
Cells(i, 1) = kol(i)
Next i
End With
End Sub



Hej
napisał: Ala
postów: 16


umieszczony:
26 października 2010
22:36

edytowany:
27 października 2010
02:24

  
Trebor,

Już wyjaśniam.

Niech będzie, że dane wejściowe pojawiają się w skoroszycie x, w arkuszu1, w kolumnie A.

Arkusz1 w kolumnie A jest indeksowany od góry do dołu w kolejności indeksów rosnących, po kolei: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ... 999, 1000, 1001,...10000, 10001, 10002, 10003,..., 100003, 100004, 100005,...,10000006, 10000007, 10000008, i tak dalej.

Czyli numer 1 indeksu to jest numer wiersza, który pojawił się najpierw kiedyś tam, obojętnie kiedy. Na przykład po 3 tygodniach spływające dane dotarły do numeru indeksu 10003 /dziesięć tysięcy trzy/. Dane spływają od dołu, tak jak wiersze w kolumnie A.

Czyli wiersz który jest na samym dole kolumny A i ma największy indeks, to ostatni numer /np. jakiś garnitur albo kosmetyk/.

Unikalnych numerów mam 1-999 w każdym arkuszu /odrębne dla różnych arkuszy wejściowych/.

No i teraz mnie interesują numery liczone od dołu: ostatnie UNIKALNE, bez powtórzeń /pojedynczo/, w wybranej ilości. W kodzie kol. ML ilość ta wynosi np. 260 ostatnich niepowtarzalnych numerów od dołu kolumny A numerów.

Innymi słowy jeśli numer występuje więcej niż 1 raz, to i tak liczę go 1 raz. Tak licząc od dołu, chcę przykładowo 260 ostatnich unikalnych numerów, albo 700 ostatnich unikalnych numerów, albo nawet 900 unikalnych numerów.

Może się zdarzyć, iż dla wyznaczenia ostatnich unikalnych 300 numerów trzeba pojechać pod górę kolumny wejściowej A o dziesięć tysięcy wierszy.

Wszystkich unikalnych numerów w kolumnie A każdego odrębnego wejściowego arkusza zakładam maksymalnie 1-999. W rzeczywistości w niektórych arkuszach może być ich mniej, ale maksymalnie 1-999 /bo są jeszcze niepełne/. Ale to raczej dla kodu nie powinno robić różnicy.

Problem polega na tym, że nigdy nie wiadomo jaki jest zakres komórek wyznaczony według sztywnych indeksów. Chodzi ZAWSZE o ilość ostatnich iluś-tam liczonych od dołu kolumny do góry.. Dane spływają w różnej ilości, raz więcej, raz mniej i nikt już nad tym nie panuje.

Poglądowe wklejenie jednej kolumny arkusza nic nie da, dopiero gdybym wkleiła kilka kolumn z tego samego arkusza z kilku dni, to widać różnicę. Ale o wiele łatwiej wyjaśnić słownie.

Odrębnych arkuszy z wejściowymi kolumnami jest znacznie więcej niż jeden. Odrębny arkusz zawiera odrębne artykuły /zakodowane numerami/ pod tymi samymi numerami od 1 do 999. Są odrębne tabele wyjściowe dla tych odrębnych arkuszy wejściowych. Niektóre arkusze mają kilka kolumn wejściowych i odpowiednio tyleż tabel wyjściowych . Tak to zostało na początku dla uproszczenia zaplanowane.

A na wyjściu są tabele posortowane rosnąco według unikalnych numerów /999 rekordów/ i unikalne numery wybrane w ilości np. 260 ostatnich /duplikaty omijamy/ mają zmieniać odpowiednio odpowiadające im rekordy w tabelach z zera na jeden. Dla każdego odrębnego arkusza danych wejściowych jest odrębna tabela wyjściowa, jak arkusz ma więcej kolumn, to ma tyle samo więcej tabel. Czyli każda kolumna wejściowa ma swoją tabelę wyjściową.

Tabele wyjściowe posiadają stałe adresy komórek.

Potrzebny program, to oczywiście jest w zamyśle tylko taki mały zabieg uzupełniający, bo poza tym cały system od dawna pracuje na prostych formułach.

Przykład:

Arkusz1 ma 5 kolumn wejściowych z numerami /ubraniami podzielonymi ze względu na wiek, płeć, itp/ i ma 5 tabel wyjściowych. Każda kolumna ma 1-999 unikalnych numerów takich samych w obrebie tegoż arkusza.

Arkusz2 ma 3 kolumny wejściowe z numerami /kosmetyki/ i ma 3 tabele wyjściowe. Każda kolumna ma 1-999 unikalnych numerów takich samych w obrebie tegoż arkusza.

Arkusz3 ma tylko jedną kolumnę wejściową, która ma 999 unikalnych numerów i koresponduje z jedną tabelą wyjściową.

Arkusz4 jak poprzedni arkusz3, ale chwilowo nie ma jeszcze puli 999 numerów, stopniowo pula rośnie i wszystkie pojawią się za jakiś czas. Tabela wyjściowa posiada już 1-999 wyzerowanych rekordów.
I tak dalej..

Dobrze byłoby wyzerować tabele wyjściowe przed każdorazowym rozpoczęciem pracy programu.


Pozdrawiam
Ala
napisał: Trebor
postów: 1209


umieszczony:
26 października 2010
20:23

  
Jeśli w miarę szybko chcesz właściwe rozwiązanie to bardzo ułatwi to załącznik z układem danych. Co oznacza określenie ostatnie dane? Chodzi o najwyższe nr, znajdujące się w najniższym wierszu, czy jest jakaś data? Czy wartości unikatowe szukamy tylko w pojedynczych arkuszach i w następnym szukanie zaczynamy od początku, czy szukanie unikatów kontynuujemy dla wszystkich wyznaczonych arkuszy.
Hej
napisał: Ala
postów: 16


umieszczony:
26 października 2010
18:20

edytowany:
26 października 2010
18:24

  
Podałam na wejściu dokładnie 260 numerów, zgodnie z założeniami w teście. Tysiąc numerów ułożonych zgodnie z przyjętym schematem.

Wszystko dokładnie tak jak w teście.

Kolumna A znika a program coś liczy.

Może sprzęt jest zbyt słaby, bo to tylko jeden rdzeń 3GHz podkręcony do 4. Może za mało pamięci RAM, tylko 2 Giga.

Kopiuję wszystko starannie.

Excel wersja 2007 PL. Pozdejmowane zabezpieczenia.

Sprzęt i oprogramowanie działają bez zarzutu, defragmentacja 2 razy dziennie, czyszczenie ciastek może tysiąc razy dziennie, czyszczenie rejestru równie częste. Często włączane antywirusy itp. Wszystko działa bez zarzutu i bezbłędnie.

Coś jest źle, ale nie znajduję błędu i będę nadal próbowała coś z tym zrobić.

Jestem tym niemniej ogromnie wdzięczna, bo każdy kod w zadanym temacie przybliża mnie milowymi krokami do ostatecznego pokonania trudności.

Pozdrowienia
Ala
napisał: ml
postów: 23


umieszczony:
26 października 2010
14:26

  
Uwagi:
1. Procedura działa tylko na jednym arkuszu wejściowym i wyjściowym (stąd pytanie o nazwę arkusza), a nie na wszystkich bo nie wiem jak masz zbudowany plik
2. W wskazanym przypadku należy podać liczbę z zakresu od 1 do 300, bo 300 to maksymalna niepowtarzalna liczba. W przypadku większej liczby procedura się 'zapętla', czyli chodzi w nieskończoność (stąd prawdopodobnie twoje przeszło godzinne obliczanie)
3. Procedura nie czyści danych w kolumnie A - a więc to nie wina procedury (procedura jedynie czyści kolumnę C w arkuszy wyjściowym, bo tam wstawia dane)
4. Procedura nie zmienia stopki - a więc to nie wina procedury
napisał: Ala
postów: 16


umieszczony:
26 października 2010
10:20

edytowany:
26 października 2010
18:31

  
Wielkie dzięki Ml !

Kod wygląda bardzo zwięźle. Interaktywny i w zamyśle, jak sądzę, ma obsługiwać wszystkie moduły i wszystkie arkusze.
Bardzo mi się to podoba i będę starała się skrzętnie wykorzystać zawarte pomysły. Jeszcze raz wielkie dzięki Ml !

Ale niestety pojawiły się jakieś problemy:
1) Program po uruchomieniu zadaje pytania i po poprawnych odpowiedziach rozpoczyna pracę.
Praca jest intensywna, temperatura na rdzeniu procesora wzrasta bezzwłocznie o 2 stopnie Celsjusza, wiatraki kręcą się hałaśliwie jak turbiny śmigłowca, lecz niestety program nie chce przerwać obliczeń. Być może trzeba dłużej czekać. Ja wyłączyłam go równo po godzinie czasu w obu próbach.


Niestety przy kilkunastu czy kilkudziesięciu arkuszach czas obliczeń godzina na każdy arkusz, to stanowczo za dużo. A być może potrzeba wielu godzin na arkusz, nie wiem.
2) Wkrótce po uruchomieniu dane wejściowe w kolumnie A znikają na zawsze. Lepiej byłoby, gdyby nie znikały..
3) Na stopce arkusza w trakcie liczenia pętli pojawia się tekst: średnia:741 licznik:519 suma:384579.


Jeszcze przed opublikowaniem kodu kol. Ml zapytałam mojego synka /mój mąż nie programuje a syn ma 9 lat i już programuje, ale niestety jeszcze nie w VBA/, czy może zna jakiś sposób na omijanie powtórzonych danych w pętli programu. Podał mi natychmiast taki pomysł, aby:
>>zadeklarować jedną tablicę jako indeks a inną jako typu logicznego i wówczas w zagnieżdżonej pętli program wpisuje ostatni wiersz kolumny danych do tablicy, zaś następne dane przed zapisaniem w tablicy każdorazowo porównuje z tymi, które już tam są i w razie duplikatów omija je i wykonuje kolejną pętlę.<<.

Niestety nie jestem programistą i dopiero muszę się sporo natrudzić, by zrozumieć, o co w wypowiedzi mojego 9-latka chodzi.
Niestety mój pomysł z zadeklarowaniem ogromnej ilości zmiennych natychmiast odrzucił jako nieekonomiczny, zaś gdy powiedziałam o moim pomyśle programu zbudowanego z samych tylko skoków GO TO, to najpierw wybałuszył oczy, potem bardzo się śmiał i na końcu pukał w czoło. Straciłam trochę autorytetu..

P.S. Oczywiście zanim uruchomiłam program, to najpierw zrobiłam wskazany testowy arkusz Excela /Excel 2007 PL/ na zaproponowane 1000 numerów, zapisałam go, następnie uruchomiłam developera, edycję kodów F7, potem skopiowałam kod z niniejszego wątku ze strony vba.mania i po najechaniu do środka kodu i kliknięciu myszką uruchomiłam F5.

Muszę tylko dodać, iż w rzeczywistości w moim skoroszycie tablice wyjściowe są stałe i posortowane rosnąco, zaś dane wejściowe spływają nieregularnie i wcale nie mają stałej ilości wierszy, tylko dynamicznie narastają do setek tysięcy i co jakiś czas się je usuwa od góry..

Uprzejmie dziękuję za wszelką pomoc.
Ala


P.S. Dziękuję Adminowi za celne i słuszne uwagi.
napisał: ml
postów: 23


umieszczony:
23 października 2010
18:55

  
Załóżmy, że w arkuszu wejściowym mam wypełnione 1000 wierszy - kolejno liczbami
wiersze od 1 do 300: od 1 do 300
wiersze od 301 do 600: od 1 do 300
wiersze od 601 do 900: od 1 do 300
wiersze od 901 do 1000: od 201 do 300.
Wybierając 260 ostatnich wierszy, powinniśmy mieć jedynki w wierszach od 901 do 1000 oraz od 641 do 800, zaś w wierszach od 801 do 900 - zera.

Sub subDuplikaty()
' zalozenie:
' 1. liczby sa w kolumnie A i nie ma pomiedzy nimi pustych komorek
' 2. arkusz wejsciowy i wyjsciowy maja taka sama kolejnosc numerow
' 3. 0/1 wstawiam do kolumny B w arkuszu wyjsciowym

  Dim arkWejscie As Worksheet ' arkusz z danymi wejsciowymi
  Dim arkWyjscie As Worksheet ' arkusz z danymi wyjsciowymi
  Dim lngIloscNumerow As Long ' ilosc numerow do pobrania
  Dim lngIndeksNumeru ' indeks numeru do pobrania
  Dim lngOstatniWiersz As Long ' ostatni wypelniony wiersz
  Dim lngPierwszyWierszy As Long ' pierwszy wiersz do pobrania
  Dim lngIndeksWiersza As Long ' indeks wiersza
  Dim lngSumaJedynek As Long ' suma jedynek

  On Error GoTo blad
  
  ' wybranie arkuszy
  Set arkWejscie = Worksheets(InputBox("Podaj nazwę arkusza wejściowego:", "Wejście", "wejscie"))
  If arkWejscie Is Nothing Then GoTo blad
  Set arkWyjscie = Worksheets(InputBox("Podaj nazwę arkusza wyjściowego:", "Wyjście", "wyjscie"))
  If arkWyjscie Is Nothing Then GoTo blad
  
  ' pytanie o ilosc wierszy
  lngIloscNumerow = CInt(InputBox("Podaj ilość numerów do pobrania:", "Ilość", "260"))
  
  ' wypelniene 0 lub 1 arkusza wejsciowego
  ' przeliczanie w nowym arkuszu
  lngOstatniWiersz = arkWejscie.Range("A1").End(xlDown).Row
  arkWyjscie.Columns(3).Clear
  Worksheets.Add
  ActiveSheet.Name = "pomoc"
  lngSumaJedynek = lngIloscNumerow
  Do
    Cells.Clear
    lngPierwszyWierszy = lngOstatniWiersz - (lngIloscNumerow - 1) - (lngIloscNumerow - lngSumaJedynek)
    arkWejscie.Range("A" & lngPierwszyWierszy & ":A" & lngOstatniWiersz).Copy Range("B1")
    Range("A1").Value = lngPierwszyWierszy
    lngIndeksNumeru = lngIloscNumerow + (lngIloscNumerow - lngSumaJedynek)
    Range("A1").AutoFill Destination:=Range("A1:A" & lngIndeksNumeru), Type:=xlFillSeries
    Columns("A:B").Sort Key1:=Range("B1"), Order1:=xlAscending, _
                        Key2:=Range("A1"), Order2:=xlDescending, _
                        Header:=xlNo, Orientation:=xlTopToBottom
    lngSumaJedynek = 1
    Cells(1, 3).Value = 1
    For lngIndeksWiersza = 2 To lngIndeksNumeru
      If Cells(lngIndeksWiersza, 2).Value = Cells(lngIndeksWiersza - 1, 2).Value Then
        Cells(lngIndeksWiersza, 3).Value = 0
      Else
        Cells(lngIndeksWiersza, 3).Value = 1
        lngSumaJedynek = lngSumaJedynek + 1
      End If
    Next
  Loop Until lngSumaJedynek = lngIloscNumerow
  
  ' koniec
  Columns("A:C").Sort Key1:=Range("A1"), Order1:=xlAscending, _
                      Header:=xlNo, Orientation:=xlTopToBottom
  Range("C1:C" & lngIndeksNumeru).Copy arkWyjscie.Range("B" & Cells(1, 1).Value)

blad:
  Set arkWejscie = Nothing
  Set arkWyjscie = Nothing
  
koniec:
  Application.DisplayAlerts = False
  Worksheets("pomoc").Delete
  Application.DisplayAlerts = True
  MsgBox "Koniec", vbInformation, "Koniec"
  
End Sub



Główny kod polega na tym, że w nowym arkuszu biorę 260 ostatnich wierszy (wraz z numerami wierszy) i sortuję je wg wartości, potem wstawiam zera w przypadku duplikatów. Następnie sumuję jedynki, czyli wiem ile mi brakuje do 260 (bo jedynkami są oznaczone niepowtarzalne dane). W kolejnym kroku zwiększam ilość wierszy o brakujące pulę i znowu sortuję, sumuję jedynki i wyliczam braki do 260. I tak do wyczerpania wartości 260. W etapie końcowym sortuje wg numeru wierszy i przenoszę do arkusza wyjściowego.
napisał: admin
postów: 613


umieszczony:
20 października 2010
00:13

  
Witam,


Po pierwsze to nie edytor drukuje Twoje posty, piszesz je sama szanowna koleżanko.
Wpiszesz co bądź, to co bądź się pokazuje.

Po drugie, tutejszy edytor pozwala na edycję napisanych już postów.

A po trzecie... cierpliwości!

pozdrawiam
admin
napisał: Ala
postów: 16


umieszczony:
19 października 2010
23:45

  
Chyba postawiłam Kolegom za trudny problem.

Rzeczywiście komunikacja z regulacją zawartości komórek w Excelu pomiedzy dwoma arkuszami to już wyższa szkoła jazdy, chyba zdecydowanie za trudny problem dla Kolegów na tym forum.

Mnie chodzi o to, aby w zależności od dynamicznie napływającej i zmieniajacej się liczby komórek i ich zawartości w jednym arkuszu, zmieniała się lub nie zmieniała automatycznie wartość rekordów w odpowiadających im tabelach w drugim arkuszu z zera na jeden.

Tego niestety nie zrobi byle kto...

Sama zastanawiam się obecnie jak do zrobić samodzielnie, zgodnie z dewizą: chcesz liczyć, to licz na siebie.

Mam obecnie dwa pomysły:

zbudować w VBA program z samych wyłącznie rozkazów skoków bezpośrednich GO TO. Te kilkanaście czy kilkadziesiat tysięcy rozkazów GO TO da się jakoś zaplanować i rozpisać na papierze a potem wprowadzić do kodu. Program skakał by w tę i z powrotem sprawdzając wartość wybranej liczby ostatnich komórek w kolumnie pierwszego arkusza i nastepnie zmieniając w odpowiednich rekordach wyzerowane komórki tabelek w drugim arkuszu !! Ten pomysł wydaje mi się najlogiczniejszy. Mam nadzieję, że program realizowany w taki sposób będzie szybki. No i to wygląda w pełni profesjonalnie, chyba nikt nie będzie polemizował?

Inna moja idea, to zadeklarować ogromny zbiór zmiennych, gdzie każda komórka w tabeli i w arkuszu do wprowadzania danych miałaby swoją zmienną. I tak można by tabele po kolei numerować literami alfabetu a kolejne komórki liczbami od 1 do 1000. To by było na początek kilkanaście do kilkudziesięciu tysięcy takich zmiennych. Czyli zmienne małyby postać: a1, a700, a999, c 297, f567, itp.

Myślę nad tym intensywnie i chyba nikt nic tu mądrzejszego nie wymyśli..

Niestety, o ile takie ogólne zaplanowanie zadania, czyli schemat blokowy programu, przychodzi mi łatwo, to jak to konkretnie zmienić na kody VBA, NIE WIEM.


Pozdrowienia dla wszystkich
Ala
napisał: Ala
postów: 16


umieszczony:
19 października 2010
23:43

edytowany:
26 października 2010
18:39

  
Tu wykasowałam mój zdublowany powyższy post.

Ala
napisał: Ala
postów: 16


umieszczony:
18 października 2010
07:56

edytowany:
26 października 2010
18:29

  
Errata

Przepraszam, ale tutejszy edytor nie wydrukował poprawnie mojego postu,

miało być:

W wyniku działania programu, program szuka np. 260 ostatnich różnych liczb i w wynikowej tabeli we właściwych rekordach zamienia ZERO na JEDEN.

Bez tego dopisku nie wiadmo czego oczekiwałabym od programu i o co proszę.

Ala


P.S. 26 października 2010 wniosłam poprawkę w moim pierwszym tekście, po słusznym i cennym pouczeniu Admina.
napisał: Ala
postów: 16


umieszczony:
18 października 2010
07:50

edytowany:
26 października 2010
18:32

  
Problem magazynowy.

Arkusze Excela zawierają dane wejściowe >> towary zakodowane w liczbach od 1 do 999.
Arkuszy wejściowych jest obecnie kilkanaście, są tam w oddzielnych arkuszach wejściowych wierzchnie ubrania pogrupowane ze względu na wiek i płeć, bielizna, galanteria, kosmetyki, itp. W przyszłości planuję zwiększenie ilości arkuszy wejściowych.

Na wyjściu są tabele wynikowe w odrębnym arkuszu Excela. Każda grupa towarów wejściowych zakodowanych w numery od 1 do 999 ma swoją tabelę wynikową.
Każda tabela wynikowa składa się z rekordów odpowiadających poszczególnym towarom w grupie. Czyli każdy zakodowany numer towaru w arkuszu wejściowym posiada odpowiadający mu rekord w tabeli wynikowej.

Na początku wszystkie rekordy we wszystkich tabelach wynikowych są wyzerowane.

Potrzebuję programu do automatycznego rejestrowania w tabelach wynikowych zadanej przeze mnie ilości ostatnich niepowtarzalnych numerów towarów z poszczególnych grup towarów arkuszy wejściowych.

Przykład.
Chcę zarejestrować automatycznie 260 OSTATNICH różnych numerów z grupy towarów z arkusza wejściowego nr 1, 170 OSTATNICH różnych numerów z grupy towarów z arkusza wejściowego nr 2 i 800 OSTATNICH różnych numerów z grupy towarów z arkusza wejściowego nr 3.
Jeżeli towary się powtarzają, to program ma rejestrować je jednokrotnie i potem szukać następnych numerów towarów, aż do znalezienia określonej ilości. Czyli dla zarejestrowania np. 260 ostatnich towarów w arkuszu nr 1 może być konieczne cofnięcie się o kilkaset pozycji/komórek kolumny, bo oczywiście towary danego rodzaju w magazynie pojawiają się w ilości większej niż w pojedynczych sztukach.
Ale w tabelach wynikowych mają być zarejestrowane ostatnie niepowtarzalne numery towarów w zadawanej ilości.

W wyniku działania programu, program szuka np. 260 ostatnich różnych liczb i w wynikowej tabeli we właściwych rekordach zamienia >>ZERO<< na >>JEDEN<<.
Chodziłoby o to, aby program można było uruchomić jednym przyciśnięciem guzika i aby dalej działał automatycznie.

Niestety nie znam się na programowaniu. Resztę potrafię zrobić sama. Potrafię w Excelu korzystać z formułek, robić bardzo ładne tabelki i kodować teksty za pomocą liczb.
Niestety nie potrafię rozgryźć powyższego problemu.
Programowanie w VBA, to jednak stanowczo męskie zajęcie.
Może ktoś z Kolegów znalazłby trochę czasu i poradził jak to zrobić. W miarę możliwości z opisem, łopatologicznie i z podaniem sposobu pobudzenia do działania.

Bardzo serdecznie z góry dziękuję za wszelką pomoc.
Ala


<-wstecz  1  dalej->
wszystkich stron: 1


Sortuj posty: z