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

  tytuł wątku:
Wątki dyskusji

Szybkie przepisywanie, bo to nie jest wcale szybkie...


otwartyotwarty rozpoczął: wally2 postów: 9



napisał: wally2
postów: 59


umieszczony:
20 czerwca 2007
08:36

edytowany:
20 czerwca 2007
10:11

  
nie mogę stwierdzić przyrostu prędkości, bo makro już poszło0w świat,
Jednak bardzo dziękuję za uwagi, następnym razem używam tylko zaprezentowanej metody, Find już mnie zawiodła kilka razy


Uwaga jest pomiar: przy ilościach 14k i 8k danych do złączenia czas metodą Find był 4min20s
metoda Match 45 sekund , jest nieźle, jeszcze raz dzięki
napisał: LAnd
postów: 107


umieszczony:
12 czerwca 2007
12:21

  
oczywiście najprostszym sposobem odczytu ilości wierszy jest

.Rows.Count

a w Excelu 97 było ich o połowę mniej
napisał: LAnd
postów: 107


umieszczony:
12 czerwca 2007
12:11

  
ale plama !!! ale do rzeczy

Oczywisty błąd , przestawienie numeru kolumny i wiersza, winno być

With .Cells(.Columns.Rows.Count, Kolumna).End(xlUp)




wszystkie odwołania do zakresów sa interpreowane w zasięgu instrukcji grupującej

With Wba.Sheets(1)

End With

- pierwszy fizycznie arkusz zeszytu Wba ( pierwsza karta arkusza w okienku zeszytu )

.Columns.Rows.Count

- ilość całkowita wierszy w arkuszu = 65536

ponieważ ilość wierszy we wszystkich kolumnach arkusza jest taka sama nie ma potrzeby wskazywania konkretnej kolumny

.Columns(1).Rows.Count



a wcześniejszy zapis jest prostszy

Prawdopodobna przyczyna

Naprzemiennie używam VBA i formuł w arkuszu. adres w formule jest wpisywany w postaci "AA7" , czyli kolumna i wiersz. Aby wpisać odwołanie bezwzględne do kolumny należy wpisać "$AA7" a do wiersza "AA$7" czyli odwrotnie niż

argumenty właściwości Cells(wiersz, kolumna)

Nie przetestowałem, z braku danych, napisanej procedury a oczywiście wywołanie właściwości Cells z numerem kolumny większym od 256 natychmiast spowodowałoby błąd wykonania.

PS. ciekaw jestem informacji o wzroście szybkośći ?
napisał: wally2
postów: 59


umieszczony:
12 czerwca 2007
11:14

  
Aby nie wyszło że czekam na gotowe pobawiłem się i muszę zapytać:
Czy
With .Cells(Kolumna, .Columns.Rows.Count).End(xlUp)

jest to samo co
With .Cells(65536, Kolumna).End(xlUp)


jesli tak to dlaczego???
Pozdrawiam
napisał: wally2
postów: 59


umieszczony:
12 czerwca 2007
09:49

  
Noooo, mocne, sprytne...., ale nie mogę zrozumiec chwytu:
'wyrażenie .Cells(Kolumna, .Columns.Rows.Count) - ostatnia celka w kolumnie "Kolumna"
  ' End(xlUp) - w wyniku wykonania tego polecenia odwołanie do ostatniej nie pustej celki w kolumnie lub pierwszej jeżeli kolumna pusta
  With .Cells(Kolumna, .Columns.Rows.Count).End(xlUp)



Kolumna = numer kolumny gdzie ma być dopisany nr umowy

Wcześniej jest
With WbA.Sheets(1)



1. zatem co mi zwróci: .Columns.Rows.Count?
2. dlaczego w Cells jako argument row jest Kolumna
.Cells(Kolumna, .Columns.Rows.Count)


3. rozumię że tym chwytem łapiesz pierwszą zajątą cele patrząc od dołu:
.Cells(Kolumna, .Columns.Rows.Count).End(xlUp)



Jak byś napisł jaśniej jak te obiekty się zrozumiały, to bym był o cały miesiąc mądrzejszy .....;)
Pozdrawiam
napisał: LAnd
postów: 107


umieszczony:
7 czerwca 2007
00:16

edytowany:
7 czerwca 2007
00:19

  
zagadnienie polega na
1. zbadaniu czy NrUmowy istnieje w zeszycie Wbbaza
dostępne funkcje arkusza :
podaj.pozycję ( w VBA Application.Worksheetfunction.Match ) - podaje numer wiersza w zakresie typu kolumna - jeżeli nie błąd to jest
licz.jeżeli ( CountIf ) - podaje ilość wystąpień w zakresie ( wolniejsza ) - >0 stwierdzono wystąpienie

2. wyszukaniu ostatniej nie pustej komórki w kolumnie Kolumna
funkcja CountA poda za mały wynik jeżeli przed ostatnią wypełnioną komórką w kolumnie będzie komórka pusta, nie powinna sytuacja zaistnieć ale może

proponuję użycie metody End z parametrem xlUp dla ostatniej komórki kolumny ( odpowiednik wciśnięcia Ctrl+Strzałka_w_górę gdy aktywna jest ostatnia
komórka kolumny ) co da w wyniku wskazanie do ostatniej nie pustej komórki w kolumnie

zmodyfikowany kod, chyba z dopalaczem



Sub DopiszUmowe(NrUmowy As Currency, WbA As Workbook)
Dim Kolumna As Integer, Wiersz

With WbA.Sheets(1)
  
  '1 pomienięcie zbędnego wyszukiwania
  If NrUmowy > 999999999999# Or NrUmowy < 100000000000# Then
    MsgBox "Numer umowy: " & NrUmowy & "jest nieprawidłowy. Nie zostanie on dopisany do bazy!!!'", vbCritical, "Uaktualnianie Bazy"
   Exit Sub ' chyba brakuje , uzupełniłem
  End If
  
  Kolumna = Left(NrUmowy, 2) - 9
  
  'ograniczenie wyszukiwania do jednej kolumny i zastosowanie funkcji arkusza Podaj.Pozycję (w VBA : Match)
  '************************** chyba 8 do 10 x szybciej !!!!!???? niż Find
  On Error Resume Next ' bo funkcja wygeneruje błąd jak nie zostanie wyszukana pozycja
  Wiersz = 0
  Wiersz = Application.WorksheetFunction.Match(NrUmowy, .Columns(Kolumna), 0)
  On Error GoTo 0
  If Wiersz > 0 Then ' funkcja zakończyła poprawnie wartość Wiersz została zmieniona
    MsgBox "Numer umowy " & NrUmowy & " już jest w bazie. Nie zostanie od powtórnie dopisany!!!", vbInformation, "Uaktualnianie Bazy"
    Exit Sub
  End If
  
  'wyrażenie .Cells(Kolumna, .Columns.Rows.Count) - ostatnia celka w kolumnie "Kolumna"
  ' End(xlUp) - w wyniku wykonania tego polecenia odwołanie do ostatniej nie pustej celki w kolumnie lub pierwszej jeżeli kolumna pusta
  With .Cells(Kolumna, .Columns.Rows.Count).End(xlUp)
   If IsEmpty(.Value) Then ' odwołanie wskazuje pustą celkę
  ' kolumna nie zawiera nie pustych celek więc prawdopodobnie dane nie mają nagłowka więc dane wpisać w tę komórkę
   .Cells(1, 1).Value = NrUmowy
  Else ' dane wpisać do następnej, która jest pusta
   .Cells(2, 1).Value = NrUmowy
  End If
 End With

End With
End Sub

napisał: LAnd
postów: 107


umieszczony:
6 czerwca 2007
21:00

  
zmiany skomentowane w tekście procedury

Sub DopiszUmowe(NrUmowy As Currency, WbA As Workbook)
Dim Kolumna As Integer

With WbA.Sheets(1)
  
  '1 pomienięcie zbędnego wyszukiwania
  If NrUmowy > 999999999999# Or NrUmowy < 100000000000# Then
    MsgBox "Numer umowy: " & NrUmowy & "jest nieprawidłowy. Nie zostanie on dopisany do bazy!!!'", vbCritical, "Uaktualnianie Bazy"
   Exit Sub ' chyba brakuje
  End If
  
  Kolumna = Left(NrUmowy, 2) - 9
  
  'ograniczenie wyszukiwania do jednej kolumny
  If Not .Columns(Kolumna).Find(What:=NrUmowy, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, _
          SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False) Is Nothing Then
    MsgBox "Numer umowy " & NrUmowy & " już jest w bazie. Nie zostanie od powtórnie dopisany!!!", vbInformation, "Uaktualnianie Bazy"
    Exit Sub
  End If
  
  .Cells(Application.WorksheetFunction.CountA(.Columns(Kolumna)) + 1, Kolumna).Value = NrUmowy
End With
End Sub



pzdrw
napisał: wally2
postów: 59


umieszczony:
6 czerwca 2007
13:41

  
Już znalazłem problem,
metoda finde spowalnia w miarę przyrostu liczb w arkuszu, mozna ją ograniczyć i powiedzmy że może być,
Jednak, gbyby ktoś jeszcze znalazł jakiś dopalacz to ja chętnie sie nauczę
napisał: wally2
postów: 59


umieszczony:
6 czerwca 2007
11:03

  
Mam zadanie typu:
Przepisać ciąg liczb 12 cyfrowych z jednego nieskładnego arkusza (są w nim w ciągu) do drugiego w ten sposób aby kolumnowo były pogrupowane po pierwszych dwóch znakach. Popełniłem w tym celu makro i mam oto taki kodzik:

Sub DopiszUmowe(NrUmowy As Currency, WbA As Workbook)
Dim Kolumna As Integer

With WbA.Sheets(1)
  If Not Cells().Find(What:=NrUmowy, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, _
          SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False) Is Nothing Then
    MsgBox "Numer umowy " & NrUmowy & " już jest w bazie. Nie zostanie od powtórnie dopisany!!!", vbInformation, "Uaktualnianie Bazy"
    Exit Sub
  End If
  
  If NrUmowy > 999999999999# Or NrUmowy < 100000000000# Then
    MsgBox "Numer umowy: " & NrUmowy & "jest nieprawidłowy. Nie zostanie on dopisany do bazy!!!'", vbCritical, "Uaktualnianie Bazy"
  End If
  Kolumna = Left(NrUmowy, 2) - 9
  .Cells(Application.WorksheetFunction.CountA(.Columns(Kolumna)) + 1, Kolumna).Value = NrUmowy
End With
End Sub

Sub test()
Dim Wbbaza As Workbook, wbDane As Workbook
Dim a As Long

Application.ScreenUpdating = False
Set wbDane = Workbooks("komornik aktualizacja-nowy.xls")
Set Wbbaza = Workbooks("Baza Umowy - Komornicy.xls")

With wbDane.Sheets("komornik")
For a = 1 To 57975
  Call DopiszUmowe(.Cells(a, 1).Value, Wbbaza)
  Application.StatusBar = a
Next a
End With
Application.StatusBar = False
Application.ScreenUpdating = True
End Sub



Sęk w tym że jak chcę poukładać 40000 liczb to trwa to b...... dłuuuggggggoooooooo.... mozna to jakoś zoptymalizować??
Zauważyłem że operacja ne cells jest czasochłonna (ok 30 celek /s), ale muszę te wartości jakoś przepisać!! Da się z tym w ogóle coś zrobić???
Proszę o sugestie...


<-wstecz  1  dalej->
wszystkich stron: 1


Sortuj posty: z