logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Automatyczne rozdzielanie danych separatorem i obramowywanie tabeli

aurora23 04 Cze 2013 08:37 2190 10
REKLAMA
  • #1 12379991
    aurora23
    Poziom 10  
    Posty: 61
    Ocena: 7
    Jestem początkującą użytkowniczką VBA (Excel 2010). Mam pewne zadanie do wykonania. Mianowicie:

    W Arkuszu1 posiadam tabelę z danymi (ilość wierszy w tej tabeli nie jest stała). Jedna kolumna w tej tabeli to numer konta oddzielany separatorami (Kropki). Moim zadaniem jest przeniesienie tej kolumny do sąsiedniego Arkusza2, do utworzonej już tabeli, w konkretną kolumnę, a następnie zastosowanie funkcji, która te dane rozdzieli tak, aby każdy element numeru konta był w innej komórce (w ten sposób z kolumny 1xn otrzymam tabelę 11xn, gdzie n to ilość rekordów w kolumnie Arkusza1).

    To co opisałam powyżej udało mi się zrobić, ale...

    1. Import danych do Arkusza2 psuje mi układ tabeli (nadpisuje komórki, które znajdują się poniżej i nie znajdują się w obrębie tabeli).

    2. Zaimportowane dane zostają rozdzielone funkcją ale tak jak powyżej, dane te nie są ani obramowane, a powyższy kod jest nieskuteczny, bo napotykając na komórkę która jest pusta wyskakuje Error.
    Przydałaby mi się tutaj pętla z licznika, ale nie wiem jak ją napisać.
    Proszę o pomoc.
    Kod: text
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #2 12380110
    marcinj12
    Poziom 40  
    Posty: 3404
    Pomógł: 1024
    Ocena: 250
    Spróbuj po takiej przeróbce, jak coś nie będzie działać - dostosuj do własnych potrzeb:
    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #3 12380394
    aurora23
    Poziom 10  
    Posty: 61
    Ocena: 7
    Dzięki serdeczne @marcinj12 za natychmiastową pomoc :)

    Jednak nie rozumiem tej części:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Co tutaj się dokładnie dzieje,
    czy deklaracja "Dim konto1_tab (odpowiednio konto2_tab) As Variant" jest poprawna?

    Błąd który się wyświetla to:
    "Can't assign to an array".

    W pomocy znalazłam coś takiego:
    Kod: text
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • Pomocny post
    #4 12380811
    marcinj12
    Poziom 40  
    Posty: 3404
    Pomógł: 1024
    Ocena: 250
    Już tłumaczę:
    Funkcja Split() jest funkcją VBA która rozdziela na tablicę swój argument - w tym wypadku wartość komórki .Cells(i, 5) - względem podanego separatora (kropka - drugi argument).
    W efekcie uzyskujesz tablicę składającą się z tylu elementów, ile "części" zwiera rozdzielany wyraz.

    Ja w moim kodzie nie deklarowałem zmiennych - jeżeli w module nie ma opcji Option Explicit to nie jest to wymagane. jeżeli masz i musisz / chcesz je zadeklarować, może to być:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    W dalszej części kodu w pętli For dla każdego elementu tablicy (odpowiednio: 1 lub 2) wpisujesz go w odpowiednią komórkę.
  • REKLAMA
  • #5 12381203
    aurora23
    Poziom 10  
    Posty: 61
    Ocena: 7
    Wielkie dzięki - to w porównaniu z moimi wypocinami ma ręce i nogi :D
    Jednak to do końca nie rozwiązuje mojego problemu nadpisywania uzupełnionych już wartości, zamiast przesuwania dołu arkusza bez naruszania jego treści i wartości w ogóle :/
  • REKLAMA
  • #6 12381691
    marcinj12
    Poziom 40  
    Posty: 3404
    Pomógł: 1024
    Ocena: 250
    Czy dobrze rozumiem, że chcesz za każdym razem po prostu DOPISYWAĆ dane do już istniejących w arkuszu "Nota_Oracle"?
    Jeżeli tak, to na przykładzie zmiennej ost_w możesz zobaczyć, jak ustalić ostatni niepusty wiersz w arkuszu. Zrób podobnie przy arkuszu z Oracla przed wejściem do pętli, a w pętli, zamiast uzależniać wiersz do którego wstawiasz od zmiennej i formułą: arkO.Cells(2 * i - 17, 10) [i podobne], użyj uzyskany numer wiersza, który zwiększysz o 2 czy o ile potrzebujesz w każdym kroku pętli.
    Jeżeli to chodzi o coś innego, to może załącz jakiś przykładowy plik z danymi i na nim wytłumacz, o co chodzi...
  • #7 12384074
    aurora23
    Poziom 10  
    Posty: 61
    Ocena: 7
    Nie, chcę po włączeniu arkusza uzupełnić danymi tabelę w arkuszu "PK", potem klikam przycisk "Twórz notę " i chcę eksportować dane z czterech kolumn do arkusza "Nota_Oracle" (tu następuje rozdzielenie względem separatora).

    Dzięki Twojej pomocy udaje mi się zrobić (wraz z przesuwaniem wierszy).

    Jednak teraz mam kolejny problem:

    1. Ja zrobić, żeby po kolejnym Kliknięciu ComandButton'a procedura się nie powtarzała (czyli wolno mi było wykonać czynność wstawiania danych tylko jeden raz), bądź w "Nota_Oracle" tabela się automatycznie "korygowała" po ówczesnej edycji danych w "PK".

    A może warto ustawić arkusz "Nota_Oracle" na domyślnie pusty przy jego otwieraniu?

    kod wstawiania:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Załączam zdjęcia arkuszy - niestety nie mogę wstawić plików Excelowskich - nie jestem ich właścicielem :P
    Załączniki:
    • obrazy.rar (98.44 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #8 12385596
    marcinj12
    Poziom 40  
    Posty: 3404
    Pomógł: 1024
    Ocena: 250
    aurora23 napisał:
    Ja zrobić, żeby po kolejnym Kliknięciu ComandButton'a procedura się nie powtarzała (czyli wolno mi było wykonać czynność wstawiania danych tylko jeden raz), bądź w "Nota_Oracle" tabela się automatycznie "korygowała" po ówczesnej edycji danych w "PK".
    A w którym momencie czyścisz (usuwasz) z arkusza "Nota Oracle" te wiersze, które wstawiłaś po kliknięciu przycisku Utwórz notę?

    Najprościej chyba pod koniec kodu przycisku kopiującego wstawić:
    Kod: text
    Zaloguj się, aby zobaczyć kod
    (oczywiście nazwa jest nazwą tego przycisku - zakładam że korzystasz z przycisków AciveX). Wtedy użytkownik dwa razy go nie wciśnie, a w arkuszu noty albo dodać jakiś przycisk "czyszczący" (usuwający) wiersze i ew. inne pola i odblokowujący przycisk z drugiego arkusza (tym razem nazwę przycisku musisz poprzedzić nazwą tego arkusza albo zmienną ustawioną na ten arkusz).

    Rozumiem, że po utworzeniu noty użytkownik może ją sobie zapisać przyciskiem Zapisz - może tam wrzucisz kod czyszczący notę i odblokowujący przycisk jej utworzenia?
    Zamiast czyścić arkusz, możesz też utworzyć jego "szablon", ukryć jego zakładkę, i zamiast usuwać wiersze i czyścić pola, każdorazowo go kopiować:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    PS. Dodaj do kodu:
    Kod: text
    Zaloguj się, aby zobaczyć kod
    na początku i
    Kod: text
    Zaloguj się, aby zobaczyć kod
    na końcu, oszczędź swoim użytkownikom migania na ekranie (i zyskaj sporo czasu przy okazji)...
  • #9 12386977
    aurora23
    Poziom 10  
    Posty: 61
    Ocena: 7
    marcinj12 napisał:

    Najprościej chyba pod koniec kodu przycisku kopiującego wstawić:
    Kod: text
    Zaloguj się, aby zobaczyć kod
    (oczywiście nazwa jest nazwą tego przycisku - zakładam że korzystasz z przycisków AciveX). Wtedy użytkownik dwa razy go nie wciśnie, a w arkuszu noty albo dodać jakiś przycisk "czyszczący" (usuwający) wiersze i ew. inne pola i odblokowujący przycisk z drugiego arkusza (tym razem nazwę przycisku musisz poprzedzić nazwą tego arkusza albo zmienną ustawioną na ten arkusz).


    okey, jeśli po pierwszym kliknięciu zablokuję przycisk to użytkownik pomyśl, że się "coś zepsuło".

    Chciałabym, żeby sytuacja wyglądała następująco:
    1. Klikam na przycisk z poziomu arkusza "PK".
    2. Jeśli w Arkuszu "Nota_Oracle" tabela była uzupełniona danymi to powyższe kliknięcie usuwa zawartość tabeli i jednocześnie wpisuje nowe dane z Arkusza "PK".

    Zatem funkcja czyszcząca musi znajdować się na samym początku funkcji przyporządkowanych to przycisku "Utwórz notę Oracle".

    Moja funkcja wygląda następująco:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Pierwsza czyści wartości pól, druga usuwa zbędne wiersze, tak aby domyślnie w tabeli były trzy puste wiersze).
    Druga nie działa tak jak powinna.... :(
    dzięki za wyrozumiałość i pomoc! :)
  • Pomocny post
    #10 12387502
    marcinj12
    Poziom 40  
    Posty: 3404
    Pomógł: 1024
    Ocena: 250
    Takie czyszczenie w pętli nie jest zbyt efektywne: lepiej od razu wyczyścić cały zakres, jak już, to możesz przecież napisać:
    Kod: text
    Zaloguj się, aby zobaczyć kod
    , a skoro i tak usuwasz pozostałe wiersze, czyszcząc jedynie 3, to po prostu:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Druga funkcja nie będzie działać z dwóch powodów:
    - po pierwsze: będziesz usuwać wiersze nawet, jeżeli arkusz będzie pusty
    - po drugie: usuwając w pętli od k = 16 do m, będziesz usuwała kolejne zwiększające się numery wierszy, chociaż po każdym kroku pętli będzie o jeden mniej i przesuną się one do góry. Jeżeli już, usuwaj w tej pętli zawsze wiersz 16.

    Ja natomiast bym to rozwiązał inaczej: pętlą For albo funkcją Find aż do ostatniego wiersza, znalazł numer wiersza jakiegoś stałego "znacznika" końca usuwania, np. szukał wartości Sporządził:, sprawdził, czy jest on większy niż 17, a jeżeli tak, usunął:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    PS. Zmienna ost_w1 powinna być typu Long, nie String. Nie musisz też robić Set arkO, jeżeli tego nie używasz - w zupełności wystarczy wrzucić nazwę tego arkusza bezpośrednio do With.
  • #11 12388589
    aurora23
    Poziom 10  
    Posty: 61
    Ocena: 7
    Serdeczne dzięki :) Zastosowałam się do porad i wszystko gra.

    Temat uznaję za zamknięty :)

Podsumowanie tematu

✨ Użytkowniczka VBA w Excelu 2010 poszukiwała pomocy w przenoszeniu danych z tabeli w Arkuszu1 do Arkusza2, gdzie kolumna z numerami konta, oddzielonymi kropkami, miała być rozdzielona na osobne komórki. Problemy obejmowały nadpisywanie istniejących danych oraz błędy przy próbie rozdzielania pustych komórek. Użytkownicy forum zaproponowali rozwiązania, w tym użycie funkcji Split do rozdzielania danych oraz metody na ustalenie ostatniego niepustego wiersza, aby uniknąć nadpisywania. Dodatkowo, zasugerowano implementację funkcji czyszczącej, aby przed każdym nowym wprowadzeniem danych usuwać stare wartości z Arkusza "Nota_Oracle". Użytkowniczka uzyskała pomoc w optymalizacji kodu oraz w zarządzaniu przyciskami aktywnymi, aby zapobiec wielokrotnemu uruchamianiu procedur.
Wygenerowane przez model językowy.
REKLAMA