Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do you map a user-defined data type to a string 3

Status
Not open for further replies.

fbloggs

Programmer
Jun 7, 1999
5
0
0
CA
I've defined a user-defined data type as per the online help example: <br>
<br>
Type EmployeeRecord ' Create user-defined type.<br>
ID As Integer ' Define elements of data type.<br>
Name As String * 20<br>
Address As String * 30<br>
Phone As Long<br>
HireDate As Date<br>
End Type<br>
<br>
and declared a variable: <br>
<br>
<br>
Dim MyRecord As EmployeeRecord<br>
<br>
Now I want to map the entire structure to a string variable (the string variable is required by a subsequent function)<br>
<br>
Dim Somestring as String<br>
<br>
This statement: <br>
<br>
Somestring = MyRecord <br>
<br>
Yields (as one would expect) a run-time type mismatch error. Is there a method of coding this to avoid such an error? <br>
<br>
Thanks. <br>
<br>

 
Microsoft sez...<br>
Only public user defined types defined in public object modules can be used as parameters or return types for public procedures of class modules or as fields of public user defined types.<br>
You attempted to use a public user defined type as a parameter or return type for a public procedure of a class module, or as a field of a public user defined type.<br>
Only public user defined types that are defined in a public<br>
object module can be used in this manner.<br>
<br>
These restrictions can be bypassed with the slow and ungainly disk "method":<br>
<br>
Dim MyRecord As EmployeeRecord<br>
Dim Somestring as String<br>
Somestring=String$(Len(MyRecord),0)<br>
ff = FreeFile<br>
Open "Filename.Ext" For Binary As #ff<br>
Put #ff, 1, MyRecord<br>
Get #ff, 1, SomeString<br>
Close #ff<br>
<br>
But why would you want to do that when Microsoft makes the conversion so "straightforward" and "easy"?<br>

 
VB does not support your problem directly. However, there is a Windows API -lstrcpyn - that does. The following example comes from a working application:<br>
<br>
<br>
Declare Function CpyUdt2Str Lib "Kernel32" Alias "lstrcpyn" (ByVal lpString1 As String, lpString2 As Any, ByVal cChars As Integer) As Integer<br>
<br>
Type CntrlRec<br>
AcctCd As String * 10<br>
PlanNum As String * 10<br>
PlanEffDt As String * 8<br>
PlanExpDt As String * 8<br>
ValDt As String * 8<br>
CalcDt As String * 8<br>
EPDt As String * 8<br>
StatusInd As String * 1<br>
AdjTypeCd As String * 1<br>
AdjNum As String * 2<br>
LastModDt As String * 8<br>
ModSectNo As String * 20<br>
Comments As String * 50<br>
AnalystInit As String * 3<br>
gstrDOSFilename As String * 12<br>
filler As String * 15<br>
End Type<br>
<br>
Global SelectedCntlRec As CntrlRec<br>
<br>
Static TempKey As String * 66, SearchKey As String * 66<br>
<br>
retval = CpyUdt2Str(SearchKey, SelectedCntlRec, 53)<br>
<br>
<br>
in this example, the first 53 bytes of the user defined data typpe are copied to a string variable. We also use the API to copy into strings and to copy user data types to user data types. The function statements follow:<br>
<br>
Declare Function CpyStr2Udt Lib "Kernel32" Alias "lstrcpyn" (lpString1 As Any, ByVal lpString2 As String, ByVal cChars As Integer) As Integer<br>
<br>
<br>
Declare Function CpyUdt2Udt Lib "Kernel32" Alias "lstrcpyn" (lpString1 As Any, lpString2 As Any, ByVal cChars As Integer) As Integer<br>

 
You have my vote for tipmaster but.... have your stopwatch ready? The crude and unpure method seems to be faster when dealing with less than 100,000 records.<br>

 
You can create another user data type (UDT) that has one string field that is as long as the UDT you're using then copy your UDT to the new one.<br>
<br>
Type EmployeeData<br>
myData as String * n<br>
End Type<br>
<br>
In your code, you would declare two variables - one for each UDT:<br>
<br>
Dim EmpRecord as EmployeeRecord<br>
Dim EmpData as EmployeeData<br>
<br>
Once you have your data in EmpRecord, do the following to copy it to a string:<br>
<br>
LSet EmpData = EmpRecord<br>
myString = EmpData.myData<br>
<br>
Don't forget to declare myString:<br>
Dim myString as String<br>
<br>
The trick is to determine the length of your UDT.<br>
<br>
' String = 2 bytes<br>
' Long = 4 bytes = String * 2<br>
' Integer = 2 bytes = String * 1<br>
' Double = 8 bytes = String * 4<br>
' Date = 8 bytes = String * 4<br>
' Currency = 8 bytes = String * 4<br>
' Boolean = 1 byte = String * 1<br>
<br>
' Add all non-String lengths and divide by 2 (round up)<br>
' then add to length of all string fields<br>
<br>
In your case, myData As String * 57<br>
<br>
I hope this helps!
 
<br>
What I've done in the past is not really use public 'type's anymore -- I've switched to using classes. So I would declare a class like this:<br>
<br>
Option Explicit<br>
<br>
Private m_ID As Integer ' Define elements of data type.<br>
Private m_Name As String * 20<br>
Private m_Address As String * 30<br>
Private m_Phone As Long<br>
Private m_HireDate As Date<br>
<br>
Public Property Let ID(RHS As Integer)<br>
m_ID = RHS<br>
End Property<br>
Public Property Get ID() As Integer<br>
ID = m_ID<br>
End Property<br>
'<br>
' other get/lets go here<br>
'<br>
<br>
Public Property Get AsString() As String<br>
Dim szTemp As String<br>
<br>
On Error GoTo AsStringError<br>
<br>
szTemp = Trim$(CStr(m_ID))<br>
szTemp = szTemp & m_Name<br>
szTemp = szTemp & m_Address<br>
szTemp = szTemp & Trim$(CStr(m_Phone))<br>
szTemp = szTemp & Trim$(CStr(m_HireDate))<br>
<br>
AsString = szTemp<br>
Exit Property<br>
<br>
AsStringError:<br>
AsString = ""<br>
End Property<br>
<br>
You probably need to decide on a format for the HireDate, since the CStr will return it in the format that the machine's locale is set to. I would suggest YYYYMMDD, since it sorts well, is Y2K ready, and is fairly obvious that it's a date.<br>
<br>
Chip H.<br>

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top