rs_dd_check is a great function to check ddic objects. But the function module does not fit me that i can call it directly because i need to use it on older systems which only have the dialog and you can not export the messages out of the fm.
so i extracted some code out of it (out of perform check_object subroutine) which should be sufficient, and it is, for tables and structures it works!!! But for every other element it's not working. :(
Basically im creating a log and then doing check and then importing from memory id 'CHE' for example CHETABLSFLIGHT into variable/table lt_log
Im sure that for other elements it is creating logs but im not sure if it fill them up...Because lt_log stays empty.
report report name.
data: objname type rsedd0-ddobjname value 'object_name', eg sflighs
eutype type rsdxx-eutype value 'object_type', eg T
enqtype type rsdeo-objtype,
protid type sy-tabix,
titletxt TYPE sprot_i-prot,
actmode TYPE ddrefstruc-mode VALUE 9,
act_res type STANDARD TABLE OF dctablres,
lt_log type STANDARD TABLE OF trlogm .
*TRANSLATE T INTO TABL ETC
call function 'INTERN_TRANSL_EUTYPE' "Sperrtyp
exporting
eutype = eutype
importing
enqueue_type = enqtype.
*CREATING LOG?
call function 'DD_OBJ_PROT_OPEN'
exporting
objectname = objname
objecttype = enqtype
level = 1
device = 'M' "Memory with report RSPUTPRT as frontend
ddfunc = 'CHE'
importing
prid = protid
exceptions
others = 01.
*CHECKING SYNTAX
case eutype .
when 'T'.
titletxt = 'CHECKING TABLES'.
call function 'DD_TABL_ACT'
exporting
device = 'M'
path = ' '
tabname = objname
timer_on = ' '
prid = protid
act_mode = actmode
protname = ''
tables
act_res_tab = act_res
exceptions
others = 03. "Abbruch -> Protokoll anzeigen
when 'V'. "View
titletxt = 'CHECKING VIEWS'.
call function 'DD_VIEW_ACT'
exporting
viewname = objname
get_state = 'M'
act_mode = actmode
prid = protid
protname = ''
exceptions
others = 03.
when others.
endcase.
TRANSLATE OBJNAME USING '/-\-'.
data lv_mem_id(200) type c.
CONCATENATE 'CHE' enqtype objname into lv_mem_id. "EX CHETABLTABLE_NAME
IMPORT lt_log FROM MEMORY ID lv_mem_id.
Related
I want to get the line where segnam = 'E1IDB02' and sdata starting with BB (-> sdata has a deeper structure. Therefore sdata has the type of the segnam. Thus means for the example further down, the first to rows have the type E1IDB02 and sdata in the third row has the type E1IDKU3. This will be clearer if you see the example coding further down) and then update a field in the structure in sdata.
For example I have following t_edidd-table:
segnam
sdata
E1IDB02
BA 123456 ...
E1IDB02
BB 987654 ...
E1IDKU3
...
One working solution:
FIELD-SYMBOLS: <ls_e1idb02> TYPE e1idb02.
LOOP AT t_edidd ASSIGNING FIELD-SYMBOL(<lv_edidd>) WHERE segnam = 'E1IDB02' AND sdata(2) = 'BB'.
ASSIGN <lv_edidd>-sdata TO <ls_e1idb02> CASTING.
<ls_e1idb02>-fiibkont = `01`.
ENDLOOP.
Or to be a little bit more clear:
FIELD-SYMBOLS: <ls_e1idb02> TYPE e1idb02.
LOOP AT t_edidd ASSIGNING FIELD-SYMBOL(<lv_edidd>) WHERE segnam = 'E1IDB02'.
ASSIGN <lv_edidd>-sdata TO <ls_e1idb02> CASTING.
IF <ls_e1idb02>-fiiquali = 'BB'. "<----
<ls_e1idb02>-fiibkont = `01`.
ENDIF.
ENDLOOP.
I wonder if there is a better solution for this?
What I have in mind is something like this (not working!):
FIELD-SYMBOLS: <ls_e1idb02> TYPE e1idb02.
ASSIGN t_edidd[ segnam = 'E1IDB02' sdata-fiiquali = 'BB' ]-sdata TO <ls_e1idb02> CASTING.
<ls_e1idb02>-fiibkont = `01`.
ASSIGN t_edidd[ segnam = 'E1IDB02' ]-sdata TO <result> CASTING. would work if I only have one entry with segnam = 'E1IDB02' but I need a second condition for sdata starting with BB or sdata field fiiquali of the structure E1IDB02.
What is working is following:
ASSIGN t_edidd[ segnam = 'E1IDB02' sdata(2) = 'BB' ]-sdata TO <ls_e1idb02> CASTING.
<ls_e1idb02>-fiibkont = `01`.
But due I want to cast the type of sdata into the structure e1idb02 getting the first 2 digits of sdata is not intentional in my opinion.
Hope my problem was understandable. If there is any information missing please let me know.
If someone wants to try this by themself I also wrote a unit test for my problem:
METHOD test.
DATA: ls_e1idb02 TYPE e1idb02,
ls_edidd TYPE edidd,
t_edidd TYPE TABLE OF edidd,
t_edidd_exp TYPE TABLE OF edidd.
ls_edidd-segnam = 'E1IDB02'.
ls_e1idb02-fiiquali = 'BA'.
ls_edidd-sdata = ls_e1idb02.
APPEND ls_edidd TO t_edidd.
APPEND ls_edidd TO t_edidd_exp.
ls_edidd-segnam = 'E1IDB02'.
ls_e1idb02-fiiquali = 'BB'.
ls_edidd-sdata = ls_e1idb02.
APPEND ls_edidd TO t_edidd.
ls_e1idb02-fiibkont = `01`.
ls_edidd-sdata = ls_e1idb02.
APPEND ls_edidd TO t_edidd_exp.
zclass->test(
CHANGING
t_edidd = t_edidd
).
cl_abap_unit_assert=>assert_equals(
act = t_edidd
exp = t_edidd_exp
).
ENDMETHOD.
I have a data model in PowerDesigner. I wrote a vba-script that changes the description of a column to the value of the comment of the column. It does well. When I look at the column-properties I can see the new description. The problem is, that the new description does not appear in the table-overview. Only when I open the column-properties and close it with the ok-button, the new description appears in the table-overview. I have a lot of columns in my model, so... has it something to do with the object-hierarchy in PowerDesigner? My script:
option explicit
Dim kind, name, obj, c, a
kind = InputBox("(T)able or (V)iew")
name = InputBox("Enter name")
If kind = "T" Then
Set obj = ActiveModel.FindChildByName(name, cls_table)
ElseIf kind = "V" Then
Set obj = ActiveModel.FindChildByName(name, cls_view)
End If
For each c in obj.columns
c.SetAttribute "Description", c.comment
Next
I'm working on a Sindows Forms application to help keep inventory of some scanners. I'm using Linq2Sql, each table has an id column. On my repair history form. I'm trying to use the serial number from the inventory table so it goes to the database and looks up the sID from the table and it returns the correct value, but when I go to send all the entered data to the history table it gets a null reference exception.
Dim db As New DataClasses1DataContext
Dim rep As Scanner_Repair_History
Dim scan = (From Scanner_Inventory In db.Scanner_Inventories Where scannerid.Text = Scanner_Inventory.SN Select Scanner_Inventory.SID).FirstOrDefault
rep.SID = scan
rep.Date_Broken = datebroke.Value
rep.Description = description.Text
rep.Send_Date = senddate.Text
rep.Recieve_Date = recievedate.Text
rep.Cost = cost.Text
rep.PlantID = plantid.Text
rep.BID = brokenid.Text
rep.RMAnumber = rmanum.Text
db.Scanner_Repair_Histories.InsertOnSubmit(rep)
db.SubmitChanges()
is that me but you didn't instanciate your "rep" variable
You don't have a defined object for placement with a 'new' keyword but I am also curious if it is a system.type.
Update based on Jinx88909
You may be returning an entire POCO Object that may be null and have a null property. You can adjust this most times by doing a null condition if you are using .NET 4.5 and up. '?.' operator.
Dim db As New DataClasses1DataContext
'I need to be a new object and not instantiated as Nothing
Dim rep As New Scanner_Repair_History
'You have the potential for a nothing value here as 'FirstOrDefault' includes a potential Nothing'.
'I would get the entire object and then just a property of it after the fact
Dim scan = (From Scanner_Inventory In db.Scanner_Inventories Where scannerid?.Text = Scanner_Inventory?.SN Select Scanner_Inventory).FirstOrDefault?.Sid
If scan IsNot Nothing Then
rep.SID = scan 'Could you maybe want scan.Id or something similar?
rep.Date_Broken = datebroke.Value
rep.Description = description.Text
rep.Send_Date = senddate.Text
rep.Recieve_Date = recievedate.Text
rep.Cost = cost.Text
rep.PlantID = plantid.Text
rep.BID = brokenid.Text
rep.RMAnumber = rmanum.Text
db.Scanner_Repair_Histories.InsertOnSubmit(rep)
db.SubmitChanges()
Else
Console.WriteLine("I got nothing for you with the inputs you put in!")
End If
I am trying to set the Text property of a dynamically created text box using a variable name, but when I use the Me.Controls(variable name).Text, I'm getting an error saying I need to set it up as "New". The name property of the text box, using a variable, was set when it was created but I don't seem to be able to retrieve using the same name.
Private Sub Example(panposition As Integer)
Dim tbfile = New TextBox()
Dim lineExample As Integer = 2
' creating a text box with a variable name
Controls.Add(tbfile) ' create the new textbox to hold the file name
tbfile.Name = "tbfile" + panposition.ToString
tbfile.Location = New Point(85, tvposition)
tbfile.Size = New Size(155, 20)
tbfile.Text = "file name"
tbfile.TextAlign = HorizontalAlignment.Left
tbfile.HideSelection = False
tbfile.TabStop = False
tbfile.AllowDrop = False
tbfile.Visible = True
' trying to update the text in the text box using file name and text retrieved from an array
Me.Controls.(arrTextVals(1, lineExample)).Text = arrTextVals(2, lineExample)
End Sub
I think the problem is in line:
Me.Controls.(arrTextVals(1, lineExample)).Text = arrTextVals(2, lineExample)
The correct way to address a control in this way is to make a reference like this
Me.Controls(i).Text = arrTextVals(2, lineExample)
where i is an integer or using the name of the desired control which in your case could be
Me.Controls(arrTextVals(1, lineExample)).Text = arrTextVals(2, lineExample)
Of course i suppose as you mentioned before that arrTextVals is a string array
Edit:
You have a dot after Me.Controls.( <- never put a . before a bracket.
I have defined a structure in my code and have a list of this structures"
Structure Parcel
Public name As String
Public type As String
End Structure
Dim ParcelList As New List(Of Parcel)
Then I'm trying to set some values to an element of the list which name is known to me
For Each myParcel As Parcel In ParcelList
If (myParcel.name = "Parcel1") Then
myParcel.type="Type1"
End If
Next
Unfortunately values in my list don't change at all. what am I doing wrong?
As Parcel is a Structure, it is passed by value so when iterating through collection, you are modifying a copy of your structure.
To better understand this case, you should understand what For Each really is. Your code can be translated into:
Dim enumerator As List(Of Parcel).Enumerator = ParcelList.GetEnumerator()
While enumerator.MoveNext()
' Here you have a local copy of your Structure
Dim myParcel As Parcel = enumerator.Current
Dim flag As Boolean = Operators.CompareString(myParcel.name, "Parcel1", False) = 0
If flag Then
' Here you modify your local copy
myParcel.type = "Type1"
End If
End While
If Parcel was a Class, it would be passed by reference so no local copy would be created and line myParcel.type = "Type1" would change proper object existing in your collection.
As already Stated this is because you are modifying a local copy of a value type. One way round this is to access the items in the list by ordinal and replace the ordinal value type with a new type:
For i As Integer = 0 To ParcelList.Count - 1
If ParcelList(i).name = "Parcel1" Then
ParcelList(i) = New Parcel With {.name = ParcelList(i).name, .type = "Type1"}
End If
Next
But really you should change the Sturcture to a Class
When checking for strings use Equals instead of '='.
If (myParcel.name.equals("Parcel1")) Then
myParcel.type="Type1"
End If
Strings are in fact 'Objects'. When you compare Strings (example StringA = StringB), you check the allocation of the String in Memory instead of the contents of the string.
Even better would be:
If (myParcel.name.ToUpper().equals(Cstr("Parcel1").toUpper())) Then
myParcel.type="Type1"
End If
That way you ignore any difference case-wise.
example:
myParcel.name = "teST"
myParcel.name.equals("test")
is False
myParcel.name.ToUpper().equals(Cstr("test").toUpper())
is true