CLASSIC ASP - Do While / Loop with 3 conditions issue - loops

I Have a SELECT with:
STATUS -1, 0 and 1.
The SELECT Statment:
SQL= "SELECT * FROM MYTABLE ORDER BY STATUS DESC"
SET MYDB = conn.Execute(SQL)
My issue:
Divide the SELECT in two parts with DO WHiLE/LOOP
PART 1:
"NOT EOF" of course
ALL STATUS 1 (priority and overule register limit)
Limit to XX registers (variable - TOTALREG)
NO STATUS -1
** STATUS 1 is the "Approved" status and can overrule the limit of registers.
I have a classroom with 20 students. (limit of registers)
but I can overbook this and make the class with 21, 22, 23 students - with "STATUS 1" = approved.
If I have only 15 approved - I will complete the limit of registers with the first 5 "STATUS 0" (Waiting for approval).
PART 2:
the rest of the SELECT
I Got a PARTIAL solution with this:
DO WHILE (((NOT MYDB.EOF) AND (CINT(COUNTREG) <= CINT(TOTALREG))) OR ((NOT MYDB.EOF) AND (MYDB("STATUS") > 0 ))) AND ((NOT MYDB.EOF) AND (MYDB("STATUS") > -1 ))
IF we have vacancies: (NOT MYDB.EOF) AND (CINT(COUNTREG) <= CINT(TOTALREG))
IF the register is approved: (NOT MYDB.EOF) AND (MYDB("STATUS") > 0 )
Exclude non-approved registers (status -1): (NOT MYDB.EOF) AND (MYDB("STATUS") > -1 )
- COUNTREG = will be incremented for each register inside the LOOP (countreg = countreg + 1)
- TOTALREG = Is a variable (number of person allowed in the classroom)
Its works with all situation.. but when I don't have registers with STATUS = -1 - I got an error '80020009'
why? any idea?

Related

Summary of Workflow History over Time

I am collecting data using a web formular and a workflow with four different status.
Started
Review by Admin
Back to User
Finished
Status 2 and 3 are repeated as long as it is needed. The application logs the history of this process and I would like to be able so see the development of the workflow over time.
The history is stored in an MS SQL Table and I can rearange it to look like this.
In the example there are two workflows (id 1 and 2) and over time the formular goes back and forth untill it is finished. I can order this by time
to derive the result I would like to have.
I dont need to have this result in wide format as long as the counting in long is correct.
I am struggling to find a way to avoid double counting status 2 and 3 and also I dont want to count status 1 later on.
I am rather looking for a strategy to obtain my desired results either in SQL or Power Query.
I tried different grouping, dense_rank and other transformations in Power Query.
Try this in PowerQuery, assumes already date sorted
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Datum", type datetime}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "zStarted", each if [Status]="Started" then 1 else if [Status]="Review by Admin" then -1 else 0),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "zReview", each if [Status]="Review by Admin" then 1 else if [Status]="Back to User" then -1 else if [Status]="Finished" then -1 else 0),
#"Added Custom2" = Table.AddColumn(#"Added Custom1", "zBackA", each if [Status]="Back to User" then 1 else null),
#"Filled Down" = Table.FillDown(#"Added Custom2",{"zBackA"}),
#"Added Custom3" = Table.AddColumn(#"Filled Down", "zBackB", each if [zBackA]=null then 0 else if [Status]="Back to User" then 1 else if [Status]="Review by Admin" then -1 else 0),
#"Added Custom4" = Table.AddColumn(#"Added Custom3", "zFinished", each if [Status]="Finished" then 1 else 0),
#"Added Index" = Table.AddIndexColumn(#"Added Custom4", "Index", 0, 1, Int64.Type),
// cumulative sum, converting to zero if <0
#"Cum1" = Table.AddColumn(#"Added Index", "Started", each List.Max(List.Combine({{0}, {List.Sum(List.FirstN(#"Added Index"[zStarted],[Index]+1))}}))),
#"Cum2" = Table.AddColumn(#"Cum1", "Review By Admin", each List.Max(List.Combine({{0}, {List.Sum(List.FirstN(#"Added Index"[zReview],[Index]+1))}}))),
#"Cum3" = Table.AddColumn(#"Cum2", "Back to User", each List.Max(List.Combine({{0}, {List.Sum(List.FirstN(#"Added Index"[zBackB],[Index]+1))}}))),
#"Cum4" = Table.AddColumn(#"Cum3", "Finished", each List.Max(List.Combine({{0}, {List.Sum(List.FirstN(#"Added Index"[zFinished],[Index]+1))}}))),
#"Removed Columns" = Table.RemoveColumns(Cum4,{"ID","zStarted", "zReview", "zBackA", "zBackB", "zFinished", "Index","Status"})
in #"Removed Columns"
ID
Datum
Status
1
06/24/22
Started
2
06/25/22
Started
1
06/26/22
Review by Admin
2
06/27/22
Review by Admin
1
06/28/22
Back to User
1
06/29/22
Review by Admin
2
06/30/22
Back to User
1
07/01/22
Back to User
1
07/02/22
Review by Admin
2
07/03/22
Review by Admin
1
07/04/22
Finished
2
07/05/22
Back to User
2
07/06/22
Review by Admin
2
07/07/22
Finished
Thanks to #horseyride i came up with my own solution using case and a similar approach within SQL
I follow a three step appraoch to avoid the double counting of changes in status by using the lagged status (sql columne action_nam)
With the lagged status I can then unambigously define the changes of the status and take the cumulutive sum.
I mark the first answer as accepted as this one helped me to find my own solution. I leave my solution with the Germany Status names just for completeness
Select top 600 created, form_uuid, Cum_Erstellt, Cum_Review, Cum_Korrektur, Cum_Fertig from (
Select *,
sum(Erstellt) over(Partition by form_uuid order by form_uuid, created) as Cum_Erstellt,
sum(Review) over(Partition by form_uuid order by form_uuid, created) as Cum_Review,
sum(Korrektur) over(Partition by form_uuid order by form_uuid, created) as Cum_Korrektur,
sum(Fertig) over(Partition by form_uuid order by form_uuid, created) as Cum_Fertig,
Erstellt+Review+Korrektur+Fertig as Vergleich
from (
Select created, form_uuid, encoded_key, action_name, lag_action,
CASE WHEN action_name = 'Datensatz erstellt und zur Bearbeitung an Datenlieferanten übergeben' THEN 1
When action_name = 'Datensatz zur Prüfung an Datensammler' and
lag_action='Datensatz erstellt und zur Bearbeitung an Datenlieferanten übergeben' THEN -1
Else 0 END AS Erstellt,
CASE WHEN action_name = 'Datensatz zur Prüfung an Datensammler' THEN 1
When action_name= 'Datensatz zur Korrektur an Datenlieferanten' Then -1
when Action_name= 'Datensatz erneut Öffnen' then 1
When action_name='Datensatz durch Datensammler bestätigt' Then -1
Else 0 END AS Review,
CASE
WHEN action_name = 'Datensatz zur Prüfung an Datensammler' and
lag_action!='Datensatz erstellt und zur Bearbeitung an Datenlieferanten übergeben' THEN -1
When action_name= 'Datensatz zur Korrektur an Datenlieferanten' Then 1
Else 0 END AS Korrektur,
CASE WHEN action_name = 'Datensatz durch Datensammler bestätigt' THEN 1
When action_name= 'Datensatz erneut Öffnen' Then -1
Else 0 END AS Fertig
from (
Select created, form_uuid, encoded_key, action_name, lag(action_name,1,NULL)
over( order by encoded_key, form_uuid, created) as lag_action
from process_instance_hist ) lag_table
) change_table
) cum_table
order by created, encoded_key
--group by created, form_uuid

Connection from sites using the websocket protocol. Ruby

There is a program that connects to the server and receives some data from it + counts server time and signals every 15 or 60 seconds.
require 'faye/websocket'
require 'eventmachine'
data = []
count = 0
EM.run {
ws = Faye::WebSocket::Client.new('wss://olymptrade.com/ws2')
ws.on :open do |event|
p [:open]
ws.send('{"uuid":"JCBQ7XBRMYSL0JB4N5","pair":"Bitcoin","size":60}')
end
ws.on :message do |event|
p [:message, event.data]
data << event.data
data_servertime = data[0].gsub(/[^\d]/, '').to_i
data.delete_at(0)
if ((data_servertime % 15) == 0)
puts "Прошло 15 секунд"
elsif ((data_servertime % 60) == 0)
puts "Прошло 60 секунд"
end
end
ws.on :close do |event|
p [:close, event.code, event.reason]
ws = nil
end
}
At startup, it constantly outputs the received data to the console:
[:message, "{\"pair\":\"Bitcoin\",\"time\":1516567298,\"open\":11146.938,\"low\":11146.938,\"high\":11146.938,\"close\":11146.938}"]
[:message, "{\"servertime\":1516567298}"]
My Questions:
How do I put the rest of the data in the array (except for servertime) namely: pair,time,open,low,high,close?
How to make it so that ONLY the information displayed on the screen is displayed, which I intentionally output using the puts command?

MATLAB data indexing issue. What is going on here?

Let I be the identity, D an orthonormal projection, and p a vector.
I realized that several of my lines of code combined to be (I-(I-D))(p) and I could just simplify it to D(p). In replacing it, I computed the new method along-side the old to double check I was computing the same thing (Earlier in my code I had a line that was D = I - D. The D you see here is that D.) I wasn't getting the same answer, and traced it to an error in indexing D.
Here you can see I'm using the debugger and checking portions of D and getting the wrong data returned.
The values in the data explorer on the right are what I'd expect them to be. Sometimes I get what I'd expect from D(:,:,k,1), and sometimes I don't, even when I make the queries right after each other.
The vectors those red arrows are pointing to should be the same. Nothing else changed or was computed between those lines, and k = 2 when the first line was run. I've closed MATLAB and restarted it and get the same issue every time. (D depends on random input, but I'm not altering the seed, so I get the same thing every first run after newly opening MATLAB. The way D is computed, I do expect D(:,:,1,1) to be the identity matrix.)
What in the world is going on? Any help is appreciated.
I have wondered if MATLAB is messing with me on purpose. Sometimes when I open it, a pop-up dialog box says I need to update my student license. I click the update button, but nothing ever happens and the dialog box never closes, so I click cancel.
Edit:
K>> whos D P
Name Size Bytes Class Attributes
D 4-D 4608 double
P 4x1x6 192 double
K>> size(D)
ans =
4 4 6 6
I've been playing around with A and B a bit, and I get the same thing. Sometimes it computes correctly and sometimes it doesn't.
K>> B=permute(P,[1,3,2])
B =
0.4155 0.27554 0.52338 0.6991 -0.11346 0.20999
0.53573 -0.83781 0.53182 -0.022364 0.60291 -0.62601
-0.49246 -0.46111 -0.39168 0.45919 0.42377 0.47074
0.54574 0.097595 0.53835 -0.54763 0.66637 0.58516
K>> A=D
A(:,:,1,1) =
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
A(:,:,2,1) =
0.99071 -0.091198 0.0020814 -0.029755
-0.091198 0.10503 0.020426 -0.292
0.0020814 0.020426 0.99953 0.0066643
-0.029755 -0.292 0.0066643 0.90473
A(:,:,3,1) =
0.46769 0.019281 -0.49725 0.036486
0.019281 0.9993 0.018011 -0.0013215
-0.49725 0.018011 0.53551 0.034083
0.036486 -0.0013215 0.034083 0.9975
A(:,:,4,1) =
0.96774 0.063488 -0.10826 0.12438
0.063488 0.87506 0.21304 -0.24477
-0.10826 0.21304 0.63673 0.41737
0.12438 -0.24477 0.41737 0.52047
A(:,:,5,1) =
0.7542 0.031217 0.42575 0.056052
0.031217 0.99604 -0.054071 -0.0071187
0.42575 -0.054071 0.26255 -0.097088
0.056052 -0.0071187 -0.097088 0.98722
A(:,:,6,1) =
0.9818 -0.10286 0.085279 0.0034902
-0.10286 0.41855 0.48208 0.01973
0.085279 0.48208 0.60031 -0.016358
0.0034902 0.01973 -0.016358 0.99933
A(:,:,1,2) =
0.99071 -0.091198 0.0020814 -0.029755
-0.091198 0.10503 0.020426 -0.292
0.0020814 0.020426 0.99953 0.0066643
-0.029755 -0.292 0.0066643 0.90473
A(:,:,2,2) =
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
A(:,:,3,2) =
0.97125 -0.15889 -0.0080537 -0.051131
-0.15889 0.12194 -0.044507 -0.28256
-0.0080537 -0.044507 0.99774 -0.014323
-0.051131 -0.28256 -0.014323 0.90907
A(:,:,4,2) =
0.91488 -0.16388 -0.18495 0.12967
-0.16388 0.6845 -0.35607 0.24964
-0.18495 -0.35607 0.59815 0.28174
0.12967 0.24964 0.28174 0.80247
A(:,:,5,2) =
0.95461 0.16812 0.10326 0.066372
0.16812 0.37733 -0.38244 -0.24582
0.10326 -0.38244 0.76511 -0.15098
0.066372 -0.24582 -0.15098 0.90295
A(:,:,6,2) =
0.99628 0.012018 0.052874 0.027665
0.012018 0.96117 -0.17085 -0.089393
0.052874 -0.17085 0.24833 -0.39329
0.027665 -0.089393 -0.39329 0.79422
A(:,:,1,3) =
0.46769 0.019281 -0.49725 0.036486
0.019281 0.9993 0.018011 -0.0013215
-0.49725 0.018011 0.53551 0.034083
0.036486 -0.0013215 0.034083 0.9975
A(:,:,2,3) =
0.97125 -0.15889 -0.0080537 -0.051131
-0.15889 0.12194 -0.044507 -0.28256
-0.0080537 -0.044507 0.99774 -0.014323
-0.051131 -0.28256 -0.014323 0.90907
A(:,:,3,3) =
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
A(:,:,4,3) =
0.98622 0.043449 -0.066709 0.085142
0.043449 0.86297 0.21038 -0.26852
-0.066709 0.21038 0.67698 0.41227
0.085142 -0.26852 0.41227 0.47382
A(:,:,5,3) =
0.62859 0.041458 0.47558 0.074661
0.041458 0.99537 -0.053085 -0.0083339
0.47558 -0.053085 0.39105 -0.0956
0.074661 -0.0083339 -0.0956 0.98499
A(:,:,6,3) =
0.95505 -0.16608 0.12371 0.0067153
-0.16608 0.38639 0.45705 0.02481
0.12371 0.45705 0.65956 -0.01848
0.0067153 0.02481 -0.01848 0.999
A(:,:,1,4) =
0.96774 0.063488 -0.10826 0.12438
0.063488 0.87506 0.21304 -0.24477
-0.10826 0.21304 0.63673 0.41737
0.12438 -0.24477 0.41737 0.52047
A(:,:,2,4) =
0.91488 -0.16388 -0.18495 0.12967
-0.16388 0.6845 -0.35607 0.24964
-0.18495 -0.35607 0.59815 0.28174
0.12967 0.24964 0.28174 0.80247
A(:,:,3,4) =
0.98622 0.043449 -0.066709 0.085142
0.043449 0.86297 0.21038 -0.26852
-0.066709 0.21038 0.67698 0.41227
0.085142 -0.26852 0.41227 0.47382
A(:,:,4,4) =
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
A(:,:,5,4) =
0.73864 0.20112 -0.011394 0.39048
0.20112 0.84524 0.0087678 -0.30047
-0.011394 0.0087678 0.9995 0.017023
0.39048 -0.30047 0.017023 0.41662
A(:,:,6,4) =
0.87322 -0.15647 0.0029936 0.29363
-0.15647 0.80689 0.0036946 0.36238
0.0029936 0.0036946 0.99993 -0.0069332
0.29363 0.36238 -0.0069332 0.31996
A(:,:,1,5) =
0.7542 0.031217 0.42575 0.056052
0.031217 0.99604 -0.054071 -0.0071187
0.42575 -0.054071 0.26255 -0.097088
0.056052 -0.0071187 -0.097088 0.98722
A(:,:,2,5) =
0.95461 0.16812 0.10326 0.066372
0.16812 0.37733 -0.38244 -0.24582
0.10326 -0.38244 0.76511 -0.15098
0.066372 -0.24582 -0.15098 0.90295
A(:,:,3,5) =
0.62859 0.041458 0.47558 0.074661
0.041458 0.99537 -0.053085 -0.0083339
0.47558 -0.053085 0.39105 -0.0956
0.074661 -0.0083339 -0.0956 0.98499
A(:,:,4,5) =
0.73864 0.20112 -0.011394 0.39048
0.20112 0.84524 0.0087678 -0.30047
-0.011394 0.0087678 0.9995 0.017023
0.39048 -0.30047 0.017023 0.41662
A(:,:,5,5) =
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
A(:,:,6,5) =
0.93556 0.24481 -0.0093576 0.016177
0.24481 0.069855 0.035553 -0.061461
-0.0093576 0.035553 0.99864 0.0023492
0.016177 -0.061461 0.0023492 0.99594
A(:,:,1,6) =
0.9818 -0.10286 0.085279 0.0034902
-0.10286 0.41855 0.48208 0.01973
0.085279 0.48208 0.60031 -0.016358
0.0034902 0.01973 -0.016358 0.99933
A(:,:,2,6) =
0.99628 0.012018 0.052874 0.027665
0.012018 0.96117 -0.17085 -0.089393
0.052874 -0.17085 0.24833 -0.39329
0.027665 -0.089393 -0.39329 0.79422
A(:,:,3,6) =
0.95505 -0.16608 0.12371 0.0067153
-0.16608 0.38639 0.45705 0.02481
0.12371 0.45705 0.65956 -0.01848
0.0067153 0.02481 -0.01848 0.999
A(:,:,4,6) =
0.87322 -0.15647 0.0029936 0.29363
-0.15647 0.80689 0.0036946 0.36238
0.0029936 0.0036946 0.99993 -0.0069332
0.29363 0.36238 -0.0069332 0.31996
A(:,:,5,6) =
0.93556 0.24481 -0.0093576 0.016177
0.24481 0.069855 0.035553 -0.061461
-0.0093576 0.035553 0.99864 0.0023492
0.016177 -0.061461 0.0023492 0.99594
A(:,:,6,6) =
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
Edit 2:
Added relevant code. I've been pausing the code and getting the errors inside the for loops at the end. (I believe it's also giving errors in S, but I've been focusing on D trying to figure it out.)
mtimesx is from here.
n = 4;
M = 6;
P = Normalize(2*rand(n,1,M)-1);
%differences between p_i and p_j
%sum of p_i and p_j
d = Normalize(repmat(permute(P,[1,3,2]),[1,1,M]) - repmat(P,[1,M,1]));
s = Normalize(repmat(permute(P,[1,3,2]),[1,1,M]) + repmat(P,[1,M,1]));
d(isnan(d)) = 0;
%orthogonal projection onto d(:,i,j), i.e. outer product of differences
%orthogonal projection onto s(:,i,j), i.e. outer product of sums
D = mtimesx(permute(d,[1,4,2,3]), permute(d,[4,1,2,3]));
S = mtimesx(permute(s,[1,4,2,3]), permute(s,[4,1,2,3]));
D2 = D;
S2 = S;
%projection onto the complement of d(:,i,j)
%projection onto the complement of s(:,i,j)
D = repmat(eye(n),[1,1,M,M]) - D;
S = repmat(eye(n),[1,1,M,M]) - S;
%total distance to the nearest subspace
PDist = zeros([1,M]);
PDist2 = PDist;
for j = 1:M
for k = 1:M-1
for l = k:M
if j~=k && j~=l
PDist(j) = PDist(j) + min(norm(P(:,1,j) - mtimes(D(:,:,k,l),P(:,1,j))), norm(P(:,1,j) - mtimes(S(:,:,k,l),P(:,1,j))));
PDist2(j) = PDist2(j) + min(norm(D2(:,:,k,1)*P(:,1,j)),norm(S2(:,:,k,1)*P(:,1,j)));
end
end
end
end
PDist-PDist2
Normalize.m
%Normalize
%Accepts an array (of column vectors) and normalizes the columns
function B = Normalize(A)
B = A./repmat(sqrt(sum(A.*A)),size(A,1),1);
end
The problem is that you indexed the matrices using the constant 1 instead of the variable l (lowercase L), both in the first example and in the code for computing PDist2.
In general it is good to avoid using variable names that look similar to each other and/or similar to numbers.
This can be avoided by using an editor that highlights uses different colors for variables and constants (I don't know if this is possible in MATLAB). In fact, this is how I found the error in your code. As you can see, when indexing D2 for the computation of PDist2 the number 1 is colored red.

Calendar buttons aren't being removed correctly - Lua

I'm trying to make a calendar to be able to switch from month to month. My problem is in removing each day button when the next or previous buttons are touched.
Here is my code for the Previous Button to switch from the current month to the previous month. My Next button code is almost exactly the same. It works perfectly fine when I tap the button for the first time, but when I tap it again, I get an error at the child:removeSelf() line, and the print message tells me there are 61 elements in the table. It seems to add extra buttons to the table every time I go to a month that hasn't been seen yet.
This is really frustrating to me because I don't see any reason why the code is making extra buttons for every month, and even if it does, each one should still get removed when the button is tapped. Can someone please help me?
local prev_function = function(event)
if event.phase == "release" then
today.year = 2012
today.month = 3
today.day = 29
today.wday = 5
if monthNum == 1 then
monthNum = 12
yearNum = yearNum - 1
elseif monthNum ~= 1 then
monthNum = monthNum - 1
end
local month = ""
if monthNum == 1 then month = "January"
elseif monthNum == 2 then month = "February"
elseif monthNum == 3 then month = "March"
elseif monthNum == 4 then month = "April"
elseif monthNum == 5 then month = "May"
elseif monthNum == 6 then month = "June"
elseif monthNum == 7 then month = "July"
elseif monthNum == 8 then month = "August"
elseif monthNum == 9 then month = "September"
elseif monthNum == 10 then month = "October"
elseif monthNum == 11 then month = "November"
elseif monthNum == 12 then month = "December"
end
monthText.text = month .. " " .. yearNum
print("Table elements before button deletion: " .. #buttonTable)
for i = #buttonTable, 1, -1 do
--[[if button[i] ~= nil then
table.remove(buttonTable)
button[i]:removeSelf()
button[i] = nil
end--]]
local child = table.remove(buttonTable)
if child ~= nil then
child:removeSelf()
child = nil
end
end
print("Table elements after button deletion: " .. #buttonTable)
next_button.alpha = 1
for i = 1, math.floor(numYears * 365.25) do
dateTable[i] = calendar.getInfo(today) --calculate the next day's date
if dateTable[i].year == yearNum and dateTable[i].month == monthNum then -- create a button if the date's year and month match the desired month
button[i] = ui.newButton{
default = "images/day.png",
over = "images/dayover.png",
text = dateTable[i].day,
size = 30,
font = native.systemFontBold,
textColor = {0, 0, 0, 255},
onEvent = addExpense_function,
offset = -35 }
if dateTable[i].wday == 1 then button[i].x = math.floor(col/2)
elseif dateTable[i].wday == 2 then button[i].x = (col * 1) + math.floor(col/2)
elseif dateTable[i].wday == 3 then button[i].x = (col * 2) + math.floor(col/2)
elseif dateTable[i].wday == 4 then button[i].x = (col * 3) + math.floor(col/2)
elseif dateTable[i].wday == 5 then button[i].x = (col * 4) + math.floor(col/2)
elseif dateTable[i].wday == 6 then button[i].x = (col * 5) + math.floor(col/2)
elseif dateTable[i].wday == 7 then button[i].x = (col * 6) + math.floor(col/2)
end
if dateTable[i].day == 1 then button[i].y = wDayBar.y + wDayBar.height/2 + math.floor(row/2)
elseif dateTable[i].wday == 1 then button[i].y = button[i-1].y + row
else button[i].y = button[i-1].y
end
end
today = dateTable[i]
table.insert(buttonTable, button[i])
--button[i].id = "button_" .. i
end
print("Table elements after button creation: " .. #buttonTable)
end
return true
end
The reason why the code in the question doesn't work (and putting the table.insert inside the if...then does work) is due to the way you're using the button table.
The loop that starts for i = 1, math.floor(numYears * 365.25) do is going to create indices from 1 to a few hundred/thousand (depending on numYears).
However, as you're using button[i]= for filling the table and you're only filling 30 or so at a time, what you're creating is a sparse table with a few non-nil entries somewhere in the middle of the table.
Now with table.insert(buttonTable, button[i]) outside the if..then what actually happens is that most of the "inserts" are inserting nil. First time around this actually works ok for 2 reasons:
inserting nil on an empty table does nothing nor does inserting nil at the end of a table
there are only a month's worth of non-nil entries in button so only a month's worth will be inserted into buttonTable
With button and buttonTable setup like this, the first part of the call to the previous or next functions works as expected and removeSelf will be called on the month's worth of buttons. However this doesn't actually remove the button from the button table.
So when you come to the numYears loop again, not only will you add your freshly created buttons to both button and buttonTable, you'll also still have the buttons that you've just called removeSelf on in button so these will be added to buttonTable again. Crucially though, they are just tables now, so when you call removeSelf on them the second time it barfs. I presume this is the cause of the error you saw.
Moving table.insert(buttonTable, button[i]) to the if...then will resolve this problem as it will only ever add freshly minted buttons to buttonTable that are then removed each time next or previous are called.
A word of caution though. The button table is a bit of a mess. After a bit of navigating around, it'll have a bunch of dead buttons (that can't be garbage collected unless you've declared the values as weak) plus a month of working buttons. If you were to try to do anything with it, the chances are that you'll get problems.
It's not clear from the code if you even need the button table. If it's not required elsewhere it would probably be safer to just hold the button references in buttonTable.
Aside from making a new table for months as well as column coordinates like Nicol suggested, I found that I needed to put the table.insert() command inside the if ... then structure. I'm not sure exactly why putting it immediately after the if ... then structure caused it to not work properly, but I'm guessing it's because the buttons are being created inside the structure.
local prev_function = function(event)
if event.phase == "release" then
--set date to start from
today.year = 2012
today.month = 2
today.day = 29
today.wday = 4
--determine new month number
if monthNum == 1 then
monthNum = 12
yearNum = yearNum - 1
elseif monthNum ~= 1 then
monthNum = monthNum - 1
end
--set month string
local month = monthTable[monthNum]
monthText.text = month .. " " .. yearNum
print("Table elements before button deletion: " .. #buttonTable)
--remove all elements in buttonTable
for i = #buttonTable, 1, -1 do
local child = table.remove(buttonTable)
if child ~= nil then
child:removeSelf()
child = nil
end
end
print("Table elements after button deletion: " .. #buttonTable)
next_button.alpha = 1
--hide prev_button if we get to the month after the month we started from
if monthNum == today.month + 1 and yearNum == today.year then
prev_button.alpha = 0
end
--generate dates for specified number of years
for i = 1, math.floor(numYears * 365.25) do
dateTable[i] = calendar.getInfo(today)
--create a button for each date inside desired month
if dateTable[i].year == yearNum and dateTable[i].month == monthNum then
button[i] = ui.newButton{
default = "images/day.png",
over = "images/dayover.png",
text = dateTable[i].day,
size = 30,
font = native.systemFontBold,
textColor = {0, 0, 0, 255},
onEvent = addExpense_function,
offset = -35 }
--set x and y
button[i].x = colTable[dateTable[i].wday]
if dateTable[i].day == 1 then button[i].y = wDayBar.y + wDayBar.height/2 + math.floor(row/2)
elseif dateTable[i].wday == 1 then button[i].y = button[i-1].y + row
else button[i].y = button[i-1].y
end
table.insert(buttonTable, button[i])
end
--change 'today' for next iteration in the for loop
today = dateTable[i]
end
print("Table elements after button creation: " .. #buttonTable)
end
return true
end

Build string in VBscript based on array of groups

I've got an ADO query (ADODB.Recordset) in VBscript that will return a result like below:
nId wstrName nParentId
0 Managed computers 2
1 Unassigned computers NULL
2 Master Server NULL
3 pseudohosts NULL
5 Server 2 0
8 Group100 5
10 Group22 5
11 Group47 5
13 Group33 5
14 Group39 5
15 Group11 5
I need to build a complete location string based on the result when I know the top level group ID.
E.g. if the top level group ID is 11 then the complete location string will be "Master Server/Managed computers/Server 2/Group47" after traversing the groups by looking at the "nId" and "nParentId" values.
The number of parent groups can vary, so I need to loop until I reach a group without a parent group. I would also like to avoid making multiple SQL queries so I'm assuming the result should get loaded into an array and then handle the information from there.
What is the best way to handle this?
Thanks in advance :)
You can work with the recordset as it is. Try this:
groupname = "..."
rs.MoveFirst
rs.Find("wstrName = '" & groupname & "'")
location = rs("wstrName")
parent = rs("nParentId")
Do Until parent = "NULL"
rs.MoveFirst
rs.Find("nId = " & parent)
location = rs("wstrName") & "/" & location
parent = rs("nParentId")
Loop
You may need to adjust the condition of the loop depending on whether the NULL values in your recordset are the string "NULL" or actual Null values.
Use a Dictionary to store your tabular data and a recursive function to build the location string.
Demo script:
Dim dicData : Set dicData = CreateObject("Scripting.Dictionary")
' nId wstrName nParentId
dicData( 0) = Array("Managed computers" , 2 )
dicData( 1) = Array("Unassigned computers", NULL)
dicData( 2) = Array("Master Server" , NULL)
dicData( 3) = Array("pseudohosts" , NULL)
dicData( 5) = Array("Server 2" , 0 )
dicData( 8) = Array("Group100" , 5 )
dicData(10) = Array("Group22" , 5 )
dicData(11) = Array("Group47" , 5 )
dicData(13) = Array("Group33" , 5 )
dicData(14) = Array("Group39" , 5 )
dicData(15) = Array("Group11" , 5 )
Dim nId
For Each nId In dicData.Keys()
WScript.Echo Right(100 + nId, 2), buildLoc(dicData, nId, Array())
Next
Function buildLoc(dicData, nId, aTmp)
ReDim Preserve aTmp(UBound(aTmp) + 1)
aTmp(UBound(aTmp)) = dicData(nId)(0)
If IsNull(dicData(nId)(1)) Then
reverseArr aTmp
buildLoc = Join(aTmp, "/")
Else
buildLoc = buildLoc(dicData, dicData(nId)(1), aTmp)
End If
End Function
Sub reverseArr(aX)
Dim nUB : nUB = UBound(aX)
Dim nUB2 : nUB2 = nUB \ 2
Dim i, vt
For i = 0 To nUB2
vt = aX(i)
aX(i) = aX(nUB - i)
aX(nUB - i) = vt
Next
End Sub
output:
00 Master Server/Managed computers
01 Unassigned computers
02 Master Server
03 pseudohosts
05 Master Server/Managed computers/Server 2
08 Master Server/Managed computers/Server 2/Group100
10 Master Server/Managed computers/Server 2/Group22
11 Master Server/Managed computers/Server 2/Group47
13 Master Server/Managed computers/Server 2/Group33
14 Master Server/Managed computers/Server 2/Group39
15 Master Server/Managed computers/Server 2/Group11

Resources