I am having trouble updating a database in a particular way that's kinda difficult to explain but I'll try. Everything works good as it is the way I have set it up. But now I need to update the value in each cell for one column a row at a time in a For loop. The loop adds the values of six previous cells and I want that sum in a Sum column for each row(record). Currently the sum column contains the wrong sum for each row and the idea is to recalculate and overwrite the old sum column value. Now I'm just a newbie to vb.net and my code will probably look very amateurish to most here so bear with me.
I am using a binding source with the appropriate datasets and table adapters and the code I post is where I'm at at this point. What this code is doing is it gets the right value to overwrite the sum cell but it doesn't write it to the database after each row iteration of the For Loop. Instead it runs through all 3482 records and writes the last rows calculations to every rows sum column cell. Example the sum for the last row is 40 and every cell in the sum column will have 40 for it's value. Now I have tried moving the update section to different location in and out of the first for loop and it pretty much does the same thing or worse. Here's my code below with a follow up after.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim z As Int16, x As Int16, y As Int16, PosX As Int16, PosY As Int16, Result As Int16, SumResult As Int16
All649_BS.MoveFirst()
Deltas_BS.MoveFirst()
For z = 1 To All649_BS.Count
SumResult = All649_BS.Current(2)
For x = 3 To 7
y = x - 1
PosX = All649_BS.Current(x)
PosY = All649_BS.Current(y)
Result = PosX - PosY
SumResult = SumResult + Result
'Deltas_BS.Current(x) = Result
DeltaSum.Text = SumResult
Next
All649_DataSet.AcceptChanges()
Deltas_BS.Current(9) = SumResult
Try
Validate()
Deltas_BS.EndEdit()
DeltasTableAdapter.Update(All649_DataSet)
Messages.Text = ("Update successful")
Catch ex As Exception
Messages.Text = ("Update failed")
End Try
All649_BS.MoveNext()
Deltas_BS.MoveNext()
SumResult = 0
Next
End Sub
This is code I tried at first and when wouldn't work decided to write code to basically rewrite all cells for each row(record) all 3482 of them. But when I set it up like that I deleted all records in the table to write to and stated fresh. But then the code wouldn't even add new records to the table. I wasted a crap load of time trying to figure out why it wouldn't add a new record just to get started. So I went back to this code. All my other functions that add new records works fine for another table in the dataset and another whole database for another set of tables. Never had an issue til now. One thing I did change that may have caused this problem is I originally had a separate bindsource, dataset, tableadapter for each table in two different databases but it was cluttered and I kinda got a better idea how these things worked and tried to streamline it all. Instead of using a bunch of datasets I made one with ALL the tables I need and then a new bindingsource and tableadapter would be created when I bound a textbox to that one dataset. It was all going fine til I tackled a second table and all went to crap when it wouldn't add new records after I ditched the whole table to rewrite it all with the new sums added. I had to do the same thing to the first table and if I remember right at the moment it succeeded with a few minor difficulties after the code ran which I corrected using Access.
I hope I explained this well enough. I saw another solution for a similar problem and they used something like .rows(i)(6) type of accessing rows and cells via indexes but I don't think you can do that with binding sources and datasets and adapters. In that solution the guy was using a dgv that was bound.
A couple things I forgot ... my update command seems to work but for all cells one same value. UPDATE Deltas SET [Sum] = ? God it was so much easier using VB6. Another weird thing wash happening when I ran the old code trying to rewrite the whole table after deleting all record.. Ran code opened table in Access and it was all out of order. I would resort by date in Access and delete the auto number column and make a new one and save and it would all go back to disordered auto number column all out of whack again. And it would be different every time. I finally got a result where all I had to do was fix the first 10 records then I tried doing the second table using the same approach only difference was instead of a 6 cell sum it was a 7 and the indexes were adjusted accordingly for the extra column. If I think of anything else I'll be back here editing.
Yup I'm back ... one more thing is I use a break point on thhe next line on the 3 to 7 loop and continue thru til it exits then check the sumresult which is always good then step thru to end of validate/update stop there and look at the tableadapter contents for current row and that value is written in and correct for the column but the database update writes the last sumresult (40) to all the cells in the sum column. So I need to find out why the update cannot update that cell in each row as it steps thru the row looper.
Well I figured it out on my own. I took 4 or 5 days off from working on the problem and got back to it last night when I posted my dilemma. Just after my last edit I found the cause. I needed to use a WHERE condition to limit the update to just the record I wanted changed. I wasn't aware that the update does the whole table without that condition.
Thanks anyway for not being able to help me out. LOL What an idiot I am ! Such a simple solution and quite obvious but like I said in the post, I'm still very new to VB.Net
Related
I need to merge several sheets and maintain data integrity. I have managed to reduce the problem to the following example and would really appreciate some help. The two columns have to be merged into one. The data in a column has to stay in the order it is originally in as each cell is a code that refers to time data. The duplicates need to be reduced to one entry as the whole data set will later be geo coded and duplicates are not tolerated.
The data is complicated and messy but essentially the problem i cannot solve can be artificially reduced to the following for simplicity:
[edit: Yellow bus stops at the following stop codes in the given order.
Blue bus stops at the following stop codes in the given order.
The order in which the buses stop cannot be changed.
The output is one list including all of the stop codes only once, retaining the order present in both lists.]
I want to change it to this:
The colour coding is just to make it clear to readers here.
The green represents where duplicates have been reduced to one (this will allow me to vlookup the data against the code and enter the data from both sheets in the same row.
The order that the codes are in must be maintained so i think i just have to move all the data down.
So, this is, (conceptually), what i was trying to do as a first stage.
Each row retains the order of data but is spread across enough rows to have enough space for both columns in one. The duplicates take the position of the one which has greater row number.
The rest of the solution follows procedurally. I can then delete duplicate codes, and create a new list with all of the values, then remove the spaces.
So if i can get to there i should be ok.
Therefore, as far as i can tell, i need to match with two formulas:
=MATCH(A1,$B$1:$B$11,0)
=MATCH(B1,$A$1:$A$11,0)
but i am not sure if this is actually the direction to take.
It gives me the row numbers on which the common entries occur, but I am not sure how recreate the necessary positions.
Perhaps i need to create these dummy columns and then count the necessary total rows, but how to do that between errors?
Or, have a dynamic running offset. But not sure how to do that either. I am finding it very difficult to wrap my head around it.
It has occurred to me that each value will be on the row number equal to the number of unique values in the two columns above it.
Many thanks in advance for any pointers / solution.
I have tried to reduce the problem down and make it as clear as possible. If anyone can see the solution and can also see where i need to focus my learning, advice on specific area of training would also be welcome.
Cheers
D
I think your problem is more easily addressed with VBA. Let's assume you are working in columns A and B (meaning, 1st and 2nd columns). In your example you have two columns and 11 rows, and since you want to handle your data row-by-row, row is the outer loop and column is the inner loop:
Sub Indexing()
Dim irow, icol, count As Integer
Dim lookIn, FoundRange As Range
count = 1
For irow = 1 To 11:
For icol = 1 To 2:
Cells(irow, icol).Select
Selection.Copy
Set lookIn = Range("F1:F" & count)
Set FoundRange = lookIn.Find(what:=Cells(irow, icol).Value, lookIn:=xlFormulas, lookat:=xlWhole)
If FoundRange Is Nothing Then
Range("F" & count).Select
ActiveSheet.Paste
count = count + 1
End If
Next icol
Next irow
End Sub
This yields the following result, output in column F:
Note that the order is slightly different from yours, but it sort of makes more sense. In your result example, you have 113 before 68, although the first number to appear in row #4 is 68. There are other differences so maybe I misunderstood the order you wanted.
You can adapt this code as follows:
If you have more columns, just replace the 2 in the icol loop by whatever number of columns you want.
If you have more rows, just replace the 11 in the irow loop by whatever number of rows you want.
If you want this to be written in a different column (not column F, as it is now), just replace F with the column letter that you want.
If you are not familiar with Macros and need help setting this up, let me know.
I'm fairly new to VBA, and have found this to be a great resource. I understand enough to generally find someone else's code and modify it to what I need it to do, but I've been stumped here. I've tried coding this several times in different ways, but can't seem to get it to work, and am not overly convinced I'm approaching it the right way to start with. I'm hoping someone is willing to help me.
Here's a theoretical example of what I'm trying to do.
I have a sheet that contains groups of orders of a certain product type with their quantities listed by the step of the process they're currently at:
Current orders in process
I need to "sort" them or re-order them so that:
1. The orders are copied into a tab based on process step, with the furthest process step being listed first working back to the closest, and...
2. Orders listed in the "complete" step need to be excluded completely, and...
3. I need to do this for multiple product types, which have different numbers of process steps, so the end column needs to be identified somehow (as a dynamic variable, or some trigger)
For the example, it would look like this:
Sorted data
I've thought through a half-dozen ways to logically go about this and tried to figure out how to then do that with code, but I'm stuck ... and I have the feeling that there is probably 1 or 2 "best" ways to go about this that someone in this community probably knows off the top of their head. Thank you in advance.
Edit: Here's my first attempt at coding the outline. I realize there are some components missing, but would love feedback on whether this seems to be a usable, or efficient approach.
Sub test1()
Dim skuStartRow As Long, skuEndRow As Long
Dim qty As Integer
Dim colCheck as long, lastCol as Long
skuStartRow = .Range("A:A").Find(what:=sku, after:=.Range("A1")).Row
skuEndRow = .Range("A:A").Find(what:=sku, after:=.Range("A1"), searchdirection:=xlPrevious).Row
' Code here to identify last column (lastCol) either by .UsedRange or by header?
For colCheck = 3 To lastCol
For rowCheck = skuStartRow To skuEndRow
qty = Cells(rowCheck, colCheck).Value
If qty <> "" Then
'copy current row and paste into destination worksheet
MsgBox qty 'test to see if correct qty is displayed
End If
Next rowCheck
Next colCheck
End Sub
Update:
Still having problems.
I've copied/pasted the whole range of orders based on product type to a new sheet where it will be sorted.
I've inserted a column and used the match/index formula provided by Variatus (autofill down) to create an index column.
Insert new column and use RANK function to create a rank ordered list, as there are duplicates in the Helper/Index column.
Used INDEX/MATCH functions to return values into rank ordered lists for both work order number and quantity value.
The code I currently have works - except that it's hard-coded using FormulaRICI = ... commands. I'm having major challenges figuring out how to convert the code to allow use of MATCH/INDEX functions with variables. I need to do this b/c depending on product type there are varying amounts of total orders, as well as varying amounts of number of steps; so I need to have a dynamic range for both rows/columns.
I've looked at a bunch of examples but can't seem to find something that works correctly. The most promising I've seen appears to be using the "replace" function in VBA, but my head's about to explode.
Any suggestions are much appreciated.
I wonder if you really need VBA for this. Please consider these steps.
Insert a column in your worksheet with this formula in row 2, copied down.
=IFERROR(MATCH(TRUE,INDEX($D2:$I2<>0,0),0),0). The range D2:I2 is defined by D2 = Step 1 and I2 = "Complete". The formula finds the first non-blank cell in the range. The column could be hidden.
Sort the sheet on the helper column, largest to smallest.
Apply a filter.
Filter on the product.
What you see at this point is the list you wish to create using VBA, however including the 'Complete' column and any other columns to the right of it.
There are a number of ways of automating this process. You might write code to either insert the formula in the helper column automatically or its result. This could be done when needed, without having a permanent extra column. You could write code to do the sorting and filtering automatically, for example, based on a currently selected product. And, finally, you might write code to copy the result to another sheet, remove the unwanted columns there, and restore the original sheet to its original condition (presumably sorted by order number).
I am having one heck of a time deleting one row from a datatable.
I'm using this code:
Dim foundRow As DataRow() = nodes.Select("identifier LIKE '*Scene Root*'")
If foundRow.Count > 0 Then foundRow(0).Delete()
nodes.AcceptChanges()
The problem is this is removing ALL rows from the datatable.
Dset.Tables("node").Rows(0).Delete()
That also deletes all rows from the table. I am a little confused as to why this is happening.
Help me regain my sanity!
I should add.. I have single stepped first example and it finds one row and it IS the row I want to delete but the actual .delete is deleting every row in the table.
Maybe its what's in the table?
It seems likely your code is running repeatedly. Try putting a Debug.WriteLine("Hello, world") in there and see how many times the message appears each time it's supposed to delete one row.
I am in need of assistance agian. When my macro works, the number 1 is populated in the final cell in column A because the coding is set up to place a number 1 or 2 depending on other data until the last row of data. Since the last row of data has necessary information in other columns, I wanted to delete the 1 in column A because it is not needed. How do I code to take away the value in the final cell of a column? I've tried referencing to it and if statements. I am sure I am missing something simple.
This is my first macro using VBA.
Thanks.
I just started working with VBA in the last day or two, but I believe the thing you are looking for is: Cells(x,y).End(xldown).ClearContents
Alternatively, I think Range("A1").End(xldown).ClearContents would be equally effective.
But I just started doing this myself, so take with spoonful of salt.
Well this is not the first time im asking these question here but I cannot make it over.
I have to delete the duplicate rows in a column. say from
range("A1:A30000") have to delete all the duplicate rows in these columns
I have used the previous solutions from my previous questions given by the programmers on the stackoverflow. They are working amazing but not these time.Last time I had each row of 15 columns but these time each row with 40 columns and none of the scripts working. The pc its just getting hang and sometimes taking 2 hrs thats not what i want. I have used the dictionary method as suggested by Issun,Jon,Reafidy and Doc brown even they are not working. I dont know why.
So I thought to use the advanced filters but im unable to delete the duplicate rows from vba. I dont find it on google, I see the manual one with the boxes but not the vba script even i find its not working fine.
Range("A1:A5").AdvancedFilter Action:=xlFilterInPlace, Unique:=True
What I have to do after applying that line. delete the duplicate rows now. I remember its like copy pasting but i dont remember the code well and something like
xltypeinvisble:delete
I dont remember the code well . I remember that i read on google now im unable to find it.
can anyone tell me to delete the duplicate entries using the advanced filter method ? do you think ,that rows had 40 columns each and that made my scripts to take long time and sometimes hang up?what might be the cause to it?
any other method which is faster is appreciated (probably dictionary one). I belive people say dictionary method but i dont know its not working fine may be the code error or not sure about the reason.its just getting hang up. so unable to know why, well its working fine for small data that i tested. but not with the bigger one.
any help is greatly appreciated!
I'm not familiar with the single line command you are looking for to delete all invisible rows at once, but you can loop through the rows in the range and manually delete them.
If this still runs too slow for you, you may want to consider adding the VBA commands to turn off screen updating and re-calculations while the macro is running.
Sub DeleteDUpes()
Dim ThisRange As Range
Dim NewRange As Range
Set ThisRange = Range("A1:A30000")
ThisRange.AdvancedFilter Action:=xlFilterInPlace, Unique:=True
' Loop through each row from bottom up, deleting rows hidden by filter
For thisrow = ThisRange.Rows.Count To 1 Step -1
Set NewRange = ThisRange.Resize(1).Offset(thisrow - 1, 0)
If NewRange.EntireRow.Hidden Then
r.EntireRow.Delete
End If
Next
End Sub