Displaying Total of spinedit values in a List Box - lazarus

I am obviously new to Delphi but I just cant seem to figure this simple in out. I need to be able to click the button ' Total for the day ' and this should add the 3 spinedit values and display the total in a List Box.

I dont have Delphi at hand here so I am not sure if SpinEdit.Value is an integer or not, but this should get you on your way:
var
Total: integer;
begin
Total := SpinEdit1.Value + SpinEdit2.Value + SpinEdit3.Value;
// now just display Total wherever you want...
...

Related

JqGrid - updating the values in all data cells

My JqGrid looks like this:
Staff
Room 1
Room 2
Jim
240
120
Dave
480
240
The staff and rooms are obtained from tables and are unknown in number at runtime. The figures (data) represent the total time spent by each staff in each room and are in minutes. I have all the above working.
All I want to do now is to iterate over all the data entries and change minutes (Eg: 240) to hours and minutes (EG 4h:0m). I'm ok with doing the math for the conversion, it's the looping over the cells and the reading and updating (just the displayed value) that has defeated me.
This is my code so far for the looping:
var $grid = jQuery('#statstab1grid')
var rows = $grid[0].rows
var crows = rows.length
var irow, row, cellsofrow
for (irow = 1; irow < crows; irow++)
{
row = rows[irow];
cellsofrow = row.cells;
alert('$(cellsofrow[0]).text() is ' + $(cellsofrow[0]).text())
alert('$(cellsofrow[1]).text() is ' + $(cellsofrow[1]).text())
}
The first alert outputs Jim then Dave, the second alert outputs nothing,
just the prompt. Even if I managed to access the data values, how would I write back to the grid the modified values?
It is good to post which version of jqGrid is used. This one is the important part.
The code you posted and your comments that nothing is alerted for cell index 1, can tell me that maybe you have a hidden field in your colModel, which value is empty. In this case it would be good to post your entire grid setup.
To the problem - you have a lot of options to do this conversion.
You can use custom formatter - more about this you can find here. This method is preferred.
You can use getRowData (without parameter) to get all the data in the grid and use setRowData to update the values. Be a careful with this method if you have a lot of data in the grid - it will be slowly in this case. See docs for grid methods
If your data is local (array) you can recalculate it, before to put it into the grid

How to properly set the size of a ListView column according to its content?

I have a number of list view controls (TListView) that are used to display data. All these list view are set to "Detail" mode and all have TImageList assigned to their "SmallIcons" properties.
I'm trying to set the width of these column based on their contents exactly in the same way as if the user double-clicked on the separator slider at the end of each of the column headers.
First, I tried to set the column width to "-1" and "-2" for auto-sizing them: not only did that fail to work perfectly (some columns containing local characters - I'm using D6 and that means ANSI strings - are too low) but it also made the display of the column extremely slow (up to 30 seconds to display a list view with 6 column and 150 items when it's instantaneous with fixed width).
I have tried to use GetTextExtent on each cell to obtain the expected width of the text, adding some margin (from 2 to 10 pixels) and the expand the width of the column if it is lower than the calculated text width. Special treatment is applied to the first column (Items.caption) to take into account the display of the icon (I add the width of the icon, plus margin, to the width of the cell's text).
That didn't work either: in many cases (for instance, displaying the date in "yyyy/mm/dd hh:nn:ss" format results in a text too large to fit in the column).
Thinking that the issue could come from the window theme engine, I've switched to use GetThemeTextExtent instead of GetTextExtent but obtained the same result.
The only thing that seems to work is to add an arbitrary large margin (20 pixels) to each column width but, of course, that produces columns that are larger than they should be.
So, is there any alternative strategy ? I don't need anything but something that will calculate the correct width once: when the list is first populated. The code behind "clicking the column separator" works just fine but I can't find how to trigger it by code (well, I guess I could send the double click messages to the header directly as a hack)
For clarification, here are the things I tried the following code:
(in call case, there is a call made to ListView.canvas.Font.Assign(ListView.font). It is not in theses functions because a single assignment is enough but the code loops on all non-autosized columns of the listview).
Edit
My initial attempt using Windows Theme API:
function _GetTextWidth1(AText: widestring; IsHeader: boolean = false): Integer;
var
ATheme: HTheme;
rValue: TRect;
iPartID: integer;
AWidetext: WideString;
const
LVP_GROUPHEADER = 6;
begin
// try to get text width using theme API
ZeroMemory(#rValue, SizeOf(rValue));
ATheme := OpenThemeData(ListView.Handle, 'LISTVIEW');
try
if not IsHeader then
iPartID := LVP_LISTITEM
else
iPartID := LVP_GROUPHEADER;
AWidetext := AText;
GetThemeTextExtent( ATheme,
ListView.Canvas.Handle,
iPartID,
LIS_NORMAL,
PWideChar(AWidetext),
-1,
DT_LEFT or DT_SINGLELINE or DT_CALCRECT,
nil,
rValue
);
finally // wrap up
CloseThemeData(ATheme);
end; // try/finally
result := rValue.Right;
end;
next attempt using DrawText/DrawTextW:
function _GetTextWidth2(AText: widestring; IsHeader: boolean = false): Integer;
var
rValue: TRect;
lFlags: Integer;
begin
// try to get text width using DrawText/DrawTextW
rValue := Rect(0, 0, 0, 0);
lFlags := DT_CALCRECT or DT_EXPANDTABS or DT_NOPREFIX or DT_LEFT or DT_EXTERNALLEADING;
DrawText(ListView.canvas.Handle, PChar(AText), Length(AText), rValue, lFlags);
//DrawTextW(ListView.canvas.Handle, PWideChar(AText), Length(AText), rValue, lFlags);
result := rValue.Right;
end;
Third attempt using delphi's TextWidth function
function _GetTextWidth3(AText: widestring; IsHeader: boolean = false): Integer;
begin
// try to get text width using delphi wrapped around GetTextExtentPoint32
result := ListView.canvas.TextWidth(Atext);
end;
In all cases, I add a margin to the resulting width: I tried values as high as 20 pixels. I also take into account the possibility that the view use icons (in which case I add the width of the icon plus the margin again to the first column).
You could use canvas.TextWidth method. But be sure to use TListView canvas (not other, i.e. TForm) and first assign a font to canvas from TListView.
For example:
var
s: integer;
begin
ListView1.AddItem('test example item', nil);
ListView1.canvas.Font.Assign(ListView1.font);
s := ListView1.canvas.TextWidth(ListView1.Items[0].Caption) + 10; //this "+10" is a small additional margin
if s > ListView1.Columns[0].Width then
ListView1.Columns[0].Width := s;
It works fine for me.

how to not allow the textbox text (number only) to start with 0 (zero)

i have an exercise to make something like a calculator. 7 TextBox. It should look like
1/2 + 2/3 = 7/6 where every number is in his own box and the + has one too. must fill in the boxes before "=" numbers ( and + ; - ; * ; / in the one in the middle) and then check with button if there are not some letters or symbols. ok made it, but the teacher ask me to write 013 in the textbox, so.. how to make it like that so if the numbers start with 0 then after clicking the button it give me error. something like:
if ...... then
msgBox("ERROR")

Visual Basic: Increasing integer every 3 clicks

So my question is pretty much what the title says: how do I get a certain integer to increase by 1 for every three clicks of a button? For example, let's say the integer is 900. I click button1 once, then again, then again, and on the third click the integer changes to 901. How can this be accomplished?
Thanks in advance.
Use a counter that is actually three times larger behind the scene. Start at 2700 instead of 900, and increase the value by one for each click.
When you want to display the value that increases every third click, you divide the counter by three:
displayValue = counter \ 3
Try this maybe this could help or give you idea
Dim click = 0
Dim num = 900
if (click % 3 = 0)
num+=1
else
click+=1
end if

What event will fire each time a report is previewed/printed?

I would like to evauluate the value of a textbox report control and hide or display it based on its value, which I can achieve easily with VBA:
If Me.Fixed.Value = 0 Then
Me.Fixed.Visible = False
End If
That works fine, but the query I am using as the report's record source allows a range of records to be printed all at once (1 per page/report), and I want the above code to run for each page/report. I am unsure of where to put the code so that each record will play by the rules. Currently, if I choose a range of 8 records, only the first one does what I want, and as I navigate through the other records in the print preview screen the format of the report is remaining unchanged when it should be changing.
I have tried the following events:
Report:
On Current
On Load
On Got Focus
On Open
On Activate
On Page
Section:
On Format
On Print
On Paint
Where can I put my VBA so that each time I scroll through/navigate the range of records returned on that report my code runs?
You need to set the Visible property back to True as well, otherwise it will remain invisible.
I'm using the Format event of the Details section:
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
If Me.Fixed = 0 Then
Me.Fixed.Visible = False
Else
Me.Fixed.Visible = True
End If
End Sub
This works in Print Preview but not in Report View. There is probably a way to get this to work with the Report View, but I never use this view.
The statement can be simplified:
Me.Fixed.Visible = Not (Me.Fixed = 0)
Note that the Visible property is not available in the Detail_Paint() event, which is the event you need to use to have the conditional formatting apply in Report View. (Which might be required if you are trying to do something fancy such as simulated hyperlinks for a drill-down effect.)
A workaround is to set the ForeColor of the text box to equal the BackColor. Although the text is technically still there, it does not "show" on the displayed report, thus simulating a hidden field.
Private Sub Detail_Paint()
' Check for even numbers
If (txtID Mod 2 = 0) Then
txtID.ForeColor = vbBlack
Else
' Set to back color to simulate hidden or transparent.
' (Assuming we are using a Normal BackStyle)
txtID.ForeColor = txtID.BackColor
End If
End Sub
Example Output:

Resources