Kolega spytał mnie niedawno w jaki sposób utworzyć pole tekstowe z zaokrąglonymi rogami, w zadanej komórce. Pole tekstowe ma być sformatowane tak samo jak komórka pod nim.
Rozwiązanie jest względnie proste aczkolwiek stopień komplikacji zależy w dużej mierze od tego jak bardzo owo pole tekstowe ma przypominać przykrywaną przez siebie komórkę. Przykład, który dziś pokażę, będzie pchełką, a więc kodu będzie niewiele. Pole tekstowe będzie miało takie samo formatowanie tekstu oraz kolor tła. Jeżeli ktoś czuje się na siłach, może sobie rozbudować ten kod o formatowanie krawędzi (obramowania) i czego tam jeszcze.
Najpierw kod:
Sub CreateTextBoxAtCell(r As Excel.Range)
Dim s As Excel.Worksheet, tb As Shape
Set s = ThisWorkbook.ActiveSheet
Set tb = s.Shapes.AddShape(msoShapeRound1Rectangle, r.Left, r.Top, r.Width, r.Height)
tb.TextEffect.Text = r.Value
tb.TextEffect.FontBold = r.Font.Bold
tb.TextEffect.FontItalic = r.Font.Italic
tb.TextEffect.FontName = r.Font.Name
tb.TextEffect.FontSize = r.Font.Size
tb.Fill.ForeColor.RGB = r.Interior.Color
tb.Visible = msoCTrue
End Sub
Teraz krótkie objaśnienie:
Sub CreateTextBoxAtCell(r As Excel.Range)
Procedura o nazwie CreateTextBoxAtCell (czyli po naszemu UtwórzPoleTekstoweWKomórce), z jednym parametrem r typu Excel.Range (czyli komórka lub zakres komórek).
Dim s As Excel.Worksheet, tb As Shape
Tu deklarujemy dwie zmienne: s typu Worksheet (przyda się za chwilę) oraz tb typu Shape. Skrót "tb" oznacza tutaj "textbox" chociaż tak naprawdę wstawiany obiekt nie będzie typu TextBox tylko ShapeRound1Rectangle, ale nie szkodzi)
Set s = ThisWorkbook.ActiveSheet
Tutaj ustawiamy zmienną s na aktualnie aktywnym skoroszycie.
Set tb = s.Shapes.AddShape(msoShapeRound1Rectangle, r.Left, r.Top, r.Width, r.Height)
A tutaj dzieje się magia właściwa. Wywołujemy metodę AddShape kolekcji Shapes bieżącego skoroszytu, a jej wynik (będący obiektem klasy Excel.Shape, a dokładniej mówiąc referencją na ten obiekt) zwracamy do zmiennej tb. Po ludzku mówiąc, wstawiamy "coś" do naszego arkusza, i od tej pory możemy się z tym "czymś" komunikować za pomocą zmiennej tb.
A co konkretnie wstawiliśmy? Wstawiliśmy msoShapeRound1Rectangle czyli zaokrąglony prostokąt. Współrzędne górnego lewego narożnika tego prostokąta pokrywają się ze współrzędnymi zadanej komórki (r.Left, r.Top), podobnie jak jego długość i szerokość (r.Width, r.Height).
Dodam jeszcze, że metoda AddShape tworzy domyślnie obiekt ukryty (niewidoczny), trzeba go potem "odkryć" osobną instrukcją. Ale po kolei:
tb.TextEffect.Text = r.Value
tb.TextEffect.FontBold = r.Font.Bold
tb.TextEffect.FontItalic = r.Font.Italic
tb.TextEffect.FontName = r.Font.Name
tb.TextEffect.FontSize = r.Font.Size
tb.Fill.ForeColor.RGB = r.Interior.Color
Tutaj ustawiamy wszystkie opcje formatowania wyglądu naszego nowo wstawionego prostokąta, a jako jego treść (tb.TextEffect.Text) wpisujemy zawartość naszej komórki (r.Value). Jeżeli ktoś czuje się na siłach, może do tej listy dopisać jeszcze formatowanie obramowania, jakieś przezroczystości, kolor tekstu i inne opcje formatowania. Sky is the limit...
tb.Visible = msoCTrue
Tutaj "odkrywamy" nasz prostokąt, czyli pokazujemy go światu.
Na zakończenie przykład wywołania powyższej procedury:
CreateTextBoxAtCell Range("C17")
Takie wywołanie spowoduje utworzenie nad komórką C17 prostokąta z zaokrąglonymi rogami oraz formatowaniem i tekstem skopiowanymi z tejże komórki.
A wiesz może jak w vba odczytać współrzędne (np. jednego z rogów) dowolnego obiektu shapes? Jednym słowem mam już dodany jakiś obiekt typu shapes i chciałbym napisać kod, który zwróci mi jego współrzędne.
Obiekt klasy Excel.Shape ma właściwości Top i Left, które określają położenie górnego lewego narożnika prostokąta opisanego na tym obiekcie:
Dzięki. Szukałem we właściwościach ale jakoś to przeoczyłem :/