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
|
|