1

Temat: programowanie w VB/WinWrap

Witam,
Czy ktoś potrafi programować w tych językach? MAm mały problem, z którym ciężko mi sobie poradzić:

Dim Val1 As Integer
 Dim Val2 As Integer
 ...
 Dim Temp As String 

 Temp = "Val1" 'Tutaj może być przypisany również "Val2" - zależy od innych zmiennych

I tu problem: Jak za pomocą zmiennej Temp odnieść się do zmiennej, której nazwa jest w niej zapisana.
Tutaj podałem zmienne Val1 oraz Val2 przykładowo - w rzeczywistości jest ich więcej i w zależności od pewnych warunków dokonywana jest selekcja jednej z nich. W tym miejscu potrzebuje zwiększyć/zmniejszych "Valx" za pomocą zmiennej Temp, lecz nie bardzo wiem jak. Może mi ktoś pomóc?
Pozdrawiam,

2

Odp: programowanie w VB/WinWrap

Nie wiem, czy problem jest jeszcze aktualny (pewnie nie). W każdym bądź razie odpowiedź jest prosta: nie da się. VB6 używa nazw tylko symbolicznie (podobnie jak np. C) i nie daje w żaden sposób możliwości odwołania się do zmiennej przez nazwę.

Problem można rozwiązać (podobnie jak w C) poprzez wskaźniki do zmiennej. Operacje na wskaźnikach do zmiennych są trochę ukrytą cecha VB6, ale zapewniam że możliwości są identyczne co w C i jest to coś, co rutynowo robię.

3

Odp: programowanie w VB/WinWrap

Problem jest jak najbardziej aktualny.
A mógłbyś wrzucić fragment kodu, który pokaże jak użyćwskaźników w tym przypadku?

4 (edytowany przez sisteczko 2012-06-17 19:09:54)

Odp: programowanie w VB/WinWrap

Proszę. Proszę wkleić poniższy kod np. do Excela/Worda. Niestety, kod wymaga użycia API w celu dereferencji wskaźnika. Należy też zwrócić uwagę na sposób deklarowania funkcji CopyMemory; można to zrobić na wiele sposobów. Przedstawiony przeze mnie (używając dyrektyw ByVal) uważam za najprostszy w danej sytuacji.

Public Declare Sub CopyMemory Lib "kernel32" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)
                   
Sub Proba()
   Dim Val1 As Integer
   Dim Val2 As Integer
   Val1 = 13
   Dim Temp As Long
   Temp = VarPtr(Val1)
   
   CopyMemory VarPtr(Val2), Temp, LenB(Val1)
   
   Debug.Print Val2
End Sub

5

Odp: programowanie w VB/WinWrap

Super, tylko obawiam się, że to nie działa w WinWrap Director, po wklejeniu do kompilatora kodu:

Option Explicit

Public Module Module1
Public Declare Sub CopyMemory Lib "kernel32" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)
    Sub Main()
    
   Dim Val1 As Integer
   Dim Val2 As Integer
   Val1 = 13
   Dim Temp As Long
   Temp = VarPtr(Val1)

   CopyMemory VarPtr(Val2), Temp, LenB(Val1)

   Debug.Print Val2
    End Sub

End Module

i uruchomieniu otrzymuję błąd "Function not found in module"
Jest jakiś inny sposób ew, mógłbym coś zmienić?

Wprawdzie problem rozwiązałem na If'ch case'ach i goto, ale wygląda to tak masakrycznie, że ze strachu, że ktoś zobaczy wolę to poprawić smile
Pozdrawiam

6

Odp: programowanie w VB/WinWrap

Chm.. po pogóglowaniu widzę, że winwrap nie obsługuje funkcji VarPtr. Bez niej nie ma szans na wskaźniki...

Można z drugiej strony, używając możliwości odwoływania się do metody klasy przez string (tak, metody klas można wywoływać przez ich nazwę symboliczną; jest to wymóg mechanizmu COM, na którym oparte są obiekty VB6).


Sub Proba2()
   Dim Kl As MojaKlasa
   Set Kl = New MojaKlasa
   Dim Temp As String
   Temp = "Val1"
   Debug.Print CallByName(Kl, Temp, VbGet)
End Sub

i definiujemy klasę "MojaKlasa" np. tak:

Option Explicit

Public Property Get Val1() As Integer
   Val1 = 13
End Property

Public Property Get Val2() As Integer
   Val2 = 10
End Property

Oczywiście wartości zwracane przez obie właściwości mogą być liczone w dowolnie skomplikowany sposób.
Poza tym, możemy mieć _kilka_ rodzajów klas (MojaProstaKlasa, MojaKlasaLiczącaCośBardzoZłożonego, KlasaOdKolegi, itp.). Znowu, przykład opiera się na VB6, a nie na WinWrap i nie gwarantuję, że na WinWrap "pójdzie". Ale przynajmniej kluczowa funkcja, CallByName, jest i ma tą samą składnię.

7

Odp: programowanie w VB/WinWrap

Przetestuje to co napisałeś, ale już chyba jutro smile
A co do VarPtr to jeżeli dobrze rozumuję to WinWrap ją obsługuje.

    Sub Main()
    
   Dim Val1 As Integer
   Dim addr As Long
   Val1 = 13
   addr = VarPtr(Val1)


   Debug.Print addr
    End Sub

Po wykonaniu takiego kodu zmienna addr zawiera wartość 65984152 (za każdym razem cztery ostatnie cysry są inne), która jest chyba adresem pamięci pod którą przechowywana jest zmienna Val1. Czyli chyba WinWrap obsługuje funkcję VarPtr, dobrze rozumuję?

8

Odp: programowanie w VB/WinWrap

>Po wykonaniu takiego kodu zmienna addr zawiera wartość 65984152 (za każdym razem cztery ostatnie cysry są inne),
>która jest chyba adresem pamięci pod którą przechowywana jest zmienna Val1. Czyli chyba WinWrap obsługuje funkcję
>VarPtr, dobrze rozumuję?

Tak. W takim razie nie powinno być problemu i z moim pierwszym kodem. Proszę napisać tylko, której funkcji dotyczy owe "Function not found in module"

9

Odp: programowanie w VB/WinWrap

Aha, wybacz - zapomniałem o najważniejszym. Na czerwono podświetliło się : "CopyMemory VarPtr(Val2), Temp, LenB(Val1)"

Jeżeli nie umieściłem deklaracji to podświetlało się przed kompilacją, po umieszczeniu deklaracji wiersz podświetlał się na czerwono po tym jak wykonywanie programu do niego doszło.

10

Odp: programowanie w VB/WinWrap

Może WinWrap nie obsługuje LenB?