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

  tytuł wątku:
Wątki dyskusji

Skopiuj wszystkie Shape "Picture ##"


otwartyotwarty rozpoczął: jamanow postów: 15



napisał: jamanow
postów: 69


umieszczony:
21 czerwca 2012
17:02

  
Uf, Uf, Uf . Wygląda na to, że biorąc pod uwagę stopień moich umiejętności będę potrzebował trochę czasu i wielokrotnego przeczytani twojej lekcji.
Kolejny raz dziękuje za cierpliwość i doskonała pomoc.
napisał: Trebor
postów: 1209


umieszczony:
21 czerwca 2012
16:03

  
Lepiej takie zawiłości wytłumaczy pomoc excela:
Cytat:
Deklarowanie tablic dynamicznych

Poprzez deklarację tablicy dynamicznej użytkownik zyskuje możliwość zmiany rozmiaru tablicy. W celu zadeklarowania takiej tablicy należy zastosować instrukcję Static, Dim, Private lub Public, pozostawiając puste nawiasy, jak w poniższym przykładzie.

Dim sngTab() As Single

Uwaga W celu niejawnego zadeklarowania tablicy wewnątrz procedury można zastosować instrukcję ReDim. Nazwę tablicy znajdującą się po instrukcji ReDim należy wprowadzić uważnie, gdyż w przypadku błędu spowoduje to utworzenie drugiej tablicy, nawet jeśli zastosowano instrukcję Option Explicit.

W procedurze umieszczonej wewnątrz zakresu tablicy instrukcja ReDim może służyć do zmiany liczby wymiarów, definiowania liczby elementów oraz definiowania górnego i dolnego ograniczenia dla każdego z wymiarów. Instrukcja ReDim może być stosowana do zmiany tablicy dynamicznej dowolnie często. Każda jednak taka operacja powoduje utratę istniejących danych w tablicy. Aby powiększyć tablicę i zachować jej dotychczasowe dane, należy użyć polecenia ReDim Preserve. Na przykład, poniższa instrukcja powiększa tablicę varTab o 10 elementów bez utraty bieżących wartości oryginalnych elementów.

ReDim Preserve varTab(UBound(varTab) + 10)

Uwaga Stosując słowo kluczowe Preserve dla tablicy dynamicznej można zmienić jedynie górne ograniczenie ostatniego wymiaru, nie można jednak zmienić liczby wymiarów.

Co do resetowania zmiennych to kolejnym problemem o jakim powinieneś poczytać jest długość życia zmiennychCytat:
Czas, w którym zmienna zachowuje swoją wartość, jest nazywany jej cyklem życia. Wartość zmiennej może zmienić się podczas jej cyklu życia, ale w dalszym ciągu zmienna przechowuje pewną wartość. Kiedy wykonanie programu opuszcza zakres zmiennej, traci ona swoją wartość.
W chwili rozpoczęcia procedury wszystkie zmienne są inicjowane. Zmienna numeryczna jest inicjowana wartością zero, ciąg znaków zmiennej długości przyjmuje wartość ciągu długości zerowej (""), natomiast ciąg znaków stałej długości jest wypełniany znakami reprezentowanymi przez kod ASCII 0 lub Chr(0). Zmienne typu Variant są inicjowane wartością Empty. Każdy element zmiennej typu zdefiniowanego przez użytkownika jest inicjowany tak, jakby był osobną zmienną.

Jeżeli deklarowana jest zmienna obiektowa, w pamięci rezerwowany jest obszar, natomiast wartość zmiennej jest ustawiana na Nothing do czasu przypisania do niej odwołania do obiektu za pomocą instrukcji Set.
Jeśli wartość zmiennej nie zmienia się podczas wykonywania programu, zmienna zachowuje swoją wartość inicjalną do czasu opuszczenia swego zasięgu.
Zmienna na poziomie procedury zadeklarowana za pomocą instrukcji Dim zachowuje swoją wartość do czasu zakończenia działania procedury. Jeśli procedura wywołuje inne procedury, zmienna zachowuje swoją wartość również podczas wykonywania tych procedur.

Jeśli zmienna na poziomie procedury jest zadeklarowana przy użyciu słowa kluczowego Static, zachowuje ona swoją wartość przez cały czas wykonywania programu w dowolnym module. Gdy cały program kończy się, zmienna traci swój zasięg i wartość. Jej cykl życia jest taki sam jak zmiennych poziomu modułu.
Zmienna na poziomie modułu różni się od zmiennej statycznej. W module standardowym lub module klasy zachowuje ona swoją wartość do czasu zatrzymania programu. W module klasy zachowuje swoją wartość tak długo, jak długo istnieje wystąpienie klasy. Zmienne na poziomie modułu zajmują zasoby pamięci do czasu zresetowania ich wartości, dlatego winny być stosowane tylko wtedy, gdy są niezbędne.

Jeśli przed instrukcją Sub lub Function zostanie umieszczone słowo kluczowe Static, wartości wszystkich zmiennych zadeklarowanych na poziomie tej procedury są zachowywane między jej wywołaniami.
i jeszcze w nagrodę EraseCytat:
Dokonuje ponownego zainicjowania elementów tablicy o stałym rozmiarze i zwalnia pamięć przydzieloną tablicy dynamicznej.

Składnia

Erase lista_tablic

Argument obowiązkowy lista_tablic jedną zmienną tablicową lub rozdzieloną przecinkami listą wielu zmiennych tablicowych, które mają ulec wymazaniu.

Użycie

Instrukcja Erase zachowuje się różnie, w zależności od tego, czy tablica ma stały rozmiar (tablica zwykła), czy też jest dynamiczna. Instrukcja Erase nie odzyskuje zawartości pamięci w przypadku stosowania jej do tablic o stałym rozmiarze. Instrukcja Erase nadaje wartości elementom tablicy o stałym rozmiarze w następujący sposób:

Rodzaj tablicy Efekt instrukcji Erase dla tablic o stałej długości
Stała tablica numeryczna Ustawia wszystkie elementy na zero.
Stała tablica ciągów (o zmiennej długości) Ustawia każdy element na ciąg o długości zerowej ("").
Stała tablica ciągów (o stałej długości) Ustawia wszystkie elementy na zero.
Stała tablica z elementami typu Variant Ustawia każdy element na wartość Empty.
Tablica z elementami typu zdefiniowanego przez użytkownika Ustawia każdy element tak, jakby był oddzielną zmienną.
Tablica obiektów Ustawia każdy element na wartość specjalną Nothing.
Instrukcja Erase zwalnia pamięć zajętą przez tablice dynamiczne. Zanim program będzie się mógł ponownie odwołać do tablicy dynamicznej, należy za pomocą instrukcji ReDim jeszcze raz zadeklarować wymiary zmiennej tablicowej.
Uf
napisał: jamanow
postów: 69


umieszczony:
20 czerwca 2012
21:53

edytowany:
20 czerwca 2012
22:44

  
Działa perfekt, wielkie dzięki.

Ostatnie pytanie.
w kodzie który napisałeś ożyłeś
Dim obrazki()

jakie zadanie spelnia tutaj ()?
normalnie variabel deklaruje poprzez AS typ:
Dim Shp As Shape, i As Integer



I jeszcze jedno :) . Czy istnieje potrzeba resetowania variabla, jeżeli tak to jak się to robi?
napisał: Trebor
postów: 1209


umieszczony:
20 czerwca 2012
19:37

  
W kodzie o którym rozmawiamy można wykorzystać do tego celu zmienną "i" np.
If i = 0 Then
    MsgBox "Brak obiektów do kopiowania"
        Else
            .Shapes.Range(obrazki).Select       'zaznacz wybrane obrazki
                Selection.Copy
                    End If



Trzeba by jeszcze zadbać aby dwa obiekty nie miały takiej samej nazwy.
napisał: jamanow
postów: 69


umieszczony:
20 czerwca 2012
18:23

  
Kolejne Dzięki za extra ifo.
Na koniec w dążeniu do optymalnego rozwiązania :). W jaki sposób uzyskać komunikat informujący, ze w aktywnym arkuszu niema szukanego Shepa. zamiast komunikatu błędu.
napisał: Trebor
postów: 1209


umieszczony:
20 czerwca 2012
16:09

  
Ponieważ zakładałem, że pisownia nazw może zawierać różnej wielkości litery, użyłem funkcji Ucase zamieniającej ciąg na napisany wielkimi literami. W Twoim porównaniu musisz użyć LINE w ten sposób napisany.
napisał: jamanow
postów: 69


umieszczony:
19 czerwca 2012
23:03

  
Jak zwykle imponujesz Trebor, twoje rozwiązanie jest bardzo eleganckim i "prostym" kodem, dokładnie tym, o co prosiłem? Serdeczne dzięki.
Przyznam szczerze ze wielokrotnie dostaje więcej niż to, o co proszę, dlatego w momencie, kiedy rozwiązania proponowane przez tęgie głowy nie są perfekcyjne staram się nie marudzić i zadawalać się tym, co dostaje. Najczęściej jest to cos, z czym sam bym sobie nie poradził.

Ale wracając do twojego kodu, popraw mnie, jeżeli się mylę. Na pierwszy rzut oka wygląda na to ze proponowane przez ciebie rozwiązanie można użyć do wszystkich Shapes uzywajac in nazwy własnej Pikture, AutoShape, Line itp.
Kontynuacja mojego domniemania bla próba:
Sub CopyAutoShape()
Dim obrazki()                       'dynamiczna tablica - bez wymiaru
Dim Shp As Shape, i As Integer

With ActiveSheet
    For Each Shp In .Shapes
      If UCase(Left(Shp.Name, 4)) = "Line" Then
      i = i + 1
      ReDim Preserve obrazki(1 To i) ' zmien wymiar tablicy zachowujac jej dotychczasowe dane
        obrazki(i) = Shp.Name
      End If
    Next Shp
.Shapes.Range(obrazki).Select       'zaznacz wybrane obrazki
Selection.Copy
End With
  
End Sub



Niestety zakonczona errorem: Program- obiekt zdefiniowany błąd 1004

????????????????
napisał: Trebor
postów: 1209


umieszczony:
18 czerwca 2012
18:53

edytowany:
18 czerwca 2012
18:55

  
Tak to co podałem to tylko w bardzo dużym uproszczeniu sposób zaznaczania obiektów za pomocą tablicy.
Kod Artika kopiuje wszystko, a następnie usuwa niepotrzebne obiekty. Jak sądziłem chciałeś tylko kopiować te obiekty, które w nazwie mają Picture. Mój kod to odwrócenie sposobu Artika. Samo zaznaczanie obiektów może mieć postać:
Sub zaznacz()
Dim obrazki() 'dynamiczna tablica - bez wymiaru
Dim Shp As Shape, i As Integer

With ActiveSheet
    For Each Shp In .Shapes
      If UCase(Left(Shp.Name, 7)) = "PICTURE" Then
      i = i + 1
      ReDim Preserve obrazki(1 To i) ' zmień wymiar tablicy zachowując jej dotychczasowe dane
        obrazki(i) = Shp.Name
      End If
    Next Shp
.Shapes.Range(obrazki).Select 'zaznacz wybrane obrazki
    
  End With
  
End Sub


Resztę łatwo dopisać wzorując się na dowolnym kodzie.
Takie odwrócenie może się przydać, gdy obiekty są duże i ich kopiowanie zabiera dużo czasu.
napisał: jamanow
postów: 69


umieszczony:
18 czerwca 2012
17:18

  
Rozwiązanie to nie jest dokładnie tym do czego dążyłem.
Jak wiesz problem mój został już rozwiązany w innym miejscu gdzie również dorzuciłeś część istotną dla końcowego rozwiązania, za co dziękuję?
napisał: Trebor
postów: 1209


umieszczony:
16 czerwca 2012
20:00

  
Czy poniższe zaznaczenie spełni wstępnie oczekiwania?
Sub Selectx4()
Dim baza(1 To 4), i As Byte

For i = 1 To 4
baza(i) = "Picture " & i
Next i

ActiveSheet.Shapes.Range(baza).Select

End Sub

napisał: jamanow
postów: 69


umieszczony:
16 czerwca 2012
19:01

  
Cytat:
Przy różnych wierszach i kolumnach obrazki nie trafią do tych samych komórek. Czy to nie przeszkadza?

I tak i nie. Najlepiej byłoby gdyby wklejanie nie naruszało formatu docelowego arkusza. Nie jest to jednak wielki problem ponieważ mam makro które ustawia format w przypadku jego przestawienia.
Pragnieniem nadrzędnym jest by wzajemne ustawienie Picture pozostało niezmienione. Tak jak w przypadku Sub Selectx4() w załączonym pliku.
napisał: Trebor
postów: 1209


umieszczony:
16 czerwca 2012
18:18

edytowany:
16 czerwca 2012
18:19

  
Zanim zmierzę się (poszukam) z możliwością zaznaczania wybranych obiektów, chcę mieć pewność, że przewidziałeś np. różne szerokości kolumn i wierszy w arkuszu z którego kopiujesz i arkuszem do którego będziesz kopiował. Przy różnych wierszach i kolumnach obrazki nie trafią do tych samych komórek. Czy to nie przeszkadza?
napisał: jamanow
postów: 69


umieszczony:
16 czerwca 2012
12:57

edytowany:
16 czerwca 2012
12:58

  
nazwa pliku rozmiar
Copy.rar 41.69 kB

OK, jeżeli Trebor nie lapie to sprawa jest prosta, mój opis wymaga uzupełnien :).
Żeby nie komplikować dodatkowo zbędnymi opisami załączam dodatek, który obrazuje mój problem.
Życzeniem moim jest to by kod dal efekt dokładnie taki jak Sub Selectx4() czyli kopiował wszystkie Shapes o określonej nazwie. W tym przypadku "Pieture"
ActiveSheet.Shapes.Range(Array("Picture 1", "Picture 2", "Picture 3", "Picture 4")).Select

Przy założeniu ze nie wiemy jakie numery maja Shape "Picture". Cos w rodzaju "Picture ##"
napisał: Trebor
postów: 1209


umieszczony:
15 czerwca 2012
18:28

  
Zbytnio nie łapię o co chodzi. Spróbuj jak poniżej:
ActiveSheet.Shapes("Picture " & 7).Copy


gdzie w nawiasie tworzysz istniejącą nazwę.
Można też próbować kopiować po kolei np.
ActiveSheet.Shapes(1).Copy

napisał: jamanow
postów: 69


umieszczony:
15 czerwca 2012
12:58

edytowany:
15 czerwca 2012
17:51

  
Próbowałem sam, Googlowalem, pytałem na innych forach i z pozoru prosta sprawa wydaje sie niemożliwa.

Problem mój polega na tym ze chce skopiować wszystkie Shape "Picture #",
Picture maja "losowo" przydzielone numery których z góry nie można przewidzieć.
kod powinien działać jak poniższy z różnica ze kopiuje tylko Shape z nazwa "Picture #"
Active.Shapes("Picture 1").Copy



lub coś takiego.
Private Sub sel()
ActiveSheet.Shapes.SelectAll
Selection.Copy
End Sub



<-wstecz  1  dalej->
wszystkich stron: 1


Sortuj posty: z