I am trying to call onEdit() to renumber rows automatically when they are moved. As far as I can tell, it is only invoked if there is a change in cell text rather than position. Is there an alternative method, or a way to monitor the spreadsheet's activity to include row repositioning?
Related
Scenario
I have an excel worksheet where I am using a certain cell (say C3) as a button functionality: Whenever the cell is selected (SelectionChange), a certain function is executed.
In order to be able to click the cell several times in a row, after performing the desired functionality I am setting the selection back to a neutral cell (say A1). This way, C3 can be selected again and the function can run again.
Problem
I would like to click the button cell (C3) several times in a row in quick succession. However, when I click it twice shortly in a row (double-click), it actually enters into edit mode for the neutral cell (A1).
I am aware of the option Cancel = True in the BeforeDoubleClick event handler. However, this doesn't work for me because it cancels the entire event altogether: With Cancel = True the second click will simply be cancelled altogether and my desired function simply won't run.
Question
Any smart ideas on how to prevent the double click while at the same time still interpreting the second click as just a normal single click?
Just expanding my comment to an answer:
Can you disable Allow editing directly in cells on File > Options > Advanced > Editing Options? Although this is a non-programming approach, it may be the simplest solution to your problem.
You could try cell security. Do not allow locked cells to be selected and use VBA to turn security on or off.
The cell could be unlocked by default and a transparent label could lock the cell on mouse rollover.
My scenario: I have a datagridview and it contains some data. User can select a row, or multiple rows in that datagridview, and they need to know a summary about those rows they selected.
Handling multiple rows in datagridview is easy enough, and I have no problem getting what the user need: Two numbers indicate how many item is selected, and their total weight in those rows. I passed that data to a small summary form to display, and I put the code to show that form under dgv.SelectionChange().
But then disaster follow: each time user select a row, that form will appear. Which is, if user select 20 rows, they will see 20 summary forms.... and any more than that, well.. you can imagine. I thought about putting something inside SelectionChange() to check if user has stopped their selection.. but can't think of any.
This seems like a very simple matter, but somehow I can't figure it out..
My question, how to know if a user has stopped their selection in a datagridview ?
I still don't have enough points to just comment, so my answer would be I don't think you can reliably without adding another control (ie, button). You can't read the users mind and since the number of rows can be variable, how would you ever know? You could try something like if the cursor leaves the DGV but that would be frought with issues as well. While it would be an extra click for those just selecting 1 row, I still think having a "Get Summary" button would be the way to go. Sort of like when selecting items to compare - you can click any number of items and while they may show which items you've picked so far in another area, the comparison table doesn't appear until you click the Compare button.
From what I understand, you actually have two options.
Add a button
Since you can't figure out when the selection is done, just add a button that will call the Form you want to display, that way you are sure that it will display only when user asks for it.
Use a timer
Another option is to use a Timer, every time the selection changed, you reset the timer to one second (to keep the example simple).
And whenever the timer does a tick, you call the Form and stop the timer. That way it will trigger one second (or less) after the user made the selection and gives him one second to change it...
Honnestly, I think the button option is the best, as you give the power to your user. Maybe they will want to select some rows but don't want to see your form, as they will only copy it to paste it somewhere else...
Symptoms
After completing a VBA macro that runs whenever a calculation event occurs, my workbook enters a strange semi-lock state. The symptoms are:
When highlighting any cell with contents, the formula bar or window flickers several times per second.
I can enter formulas and formula arrays in any blank cell and calculation proceeds as normal, although flickering continues.
Switching between auto/manual calculate has no effect on the flickering.
The array formulas associated with the calculation event take on a strange property: While editing them in the formula bar, if I press ENTER nothing happens. Normally for an array formula I would get an error, but for these, the cursor just stays in the formula editing window unless I press CTRL+SHIFT+ENTER. See below for relevant details on the application.
For context:
My application is a VBA add-in that uses UDF's to pull read-only data from a remote MySQL server. The workflow involves piggy-backing on the calculate event in order to get around the fact that excel UDF's can't alter the size of the formula that is calling them. The process goes:
user enters formula
formula creates a 'query' item that is stored in a global collection
upon calculation, a subroutine processes all the queries, sends SQL queries to the remote database, receives the response, resizes the formula region to fit the size of the returned data, and stores the returned data in another global collection
when the calling region is resized, the formula function automatically runs again. This time, it sees that data is waiting in the second global collection and that the data is the right size, and it writes the data to the worksheet, preserving the formula
Based on the debug window, it looks like my calculate event has finished when the flickering begins to occur. All of my global collections are empty. I'm not sure what the application is doing when it locks in this way or how to get more data on the problem. It only occurs occasionally.
Has anyone encountered something like this before?
Hopefully it helps someone who has the same or similar problem. In my case there were no formulas in workbook and no calculate events. Still - after macro executed, values populated by the macro in formula window were flickering.
After debugging, it came out that on line with array paste, macro was repeatedly going back to start of procedure, while pasting only part of data. After I fixed calculation of array values, so that arguments for timeserial functions were correct, pasting complete array succeeded without retreating to start of sub.
I have a table that has a series of filters across the top of it (as per usual.) This table feeds a massive graph that has multiple series of data in it. In order to hide different series of data I have grouped the information in the tables. I can then click on the minus button to remove a series of data from the graph by collapsing the group, or click the plus button to add it back in the same way. Yes, I know, not the best solution. It was an early effort, what can I say? My default is for all data to be hidden (all groups collapsed).
I have a user (a very important user) who wants to be able to use the filters across the top to find the specific series they are looking for. The filter will find the collapsed series just fine, but the series will not display because it is collapsed.
So, What I'm trying to do is get all groups to auto-expand when the filter is activated. This should work as a stop gap measure until I can simply redesign the chart.
The Problem: I can't figure out how to make Excel notice when the filter has been clicked on (or otherwise used). I've tried using Worksheet_Change and Worksheet_SelectionChange, but neither of them activate the code I have set up in the listener. That code, FYI, checks to make sure the filter is in use and adjusts the groupings accordingly. It should work fine if I can just get Excel to notice it's existence.
I've looked into making my own listener, but there's nowhere in the code I can insert it to make it activate. I just need a listener that will notice when the filter has been changed.
Any thoughts? After an hour of searching I'm stumped...
Okay, after some research I figured out a work around. The big problem here is that changing a filter does not raise any events that can be heard by VBA. Big problem.
Simple Solution: Create something that will activate a listener.
What I ended up doing was finding a cell somewhere outside of my table that wasn't going to be affected by the collapses, then I added a very simple formula (=Count(H:H)). Now whenever the table is collapsed the count is affected which activates the Worksheet_Calculate listener. And voila! I can dynamically change the groupings all I want :-).
So there you have it. If you need to detect a filter being activated via a Worksheet listener, you just need to set up a formula to activate the calculate listener.
Reference: [MSDN Article on the same thing].1 There is apparently a much more robust way to fix this problem as well which is detailed in the article.
You mentioned table, so assuming it's PivotTable you may try,
Worksheet_PivotTableUpdate(ByVal Target As PivotTable)
If it's simply a Targe Range change then,
If Intersect(Target, Range("A2"))
I am adding an undo feature for a DataGridView using the Command Design Pattern.
To create the EditCommand, I have to know what was the previous value of the cell, so I can re-enter it in case the user hits undo.
I'm doing it using the CellBeginEdit and CellEndEdit events.
With the CellBeginEdit, I save the value of the cell in a private variable and at the CellEndEdit function, I use the saved value to create the EditCommand.
It's working fine, but I wonder if there is a more saner way to do it. Maybe a event that holds together the previous and the new cell value.
Bonus points if I could actually prevent the DataGridView from updating itself and let the EditCommand do it.
I recently implemented Undo / Redo in a large WPF application, and was able to extract the Undo / Redo logic into a stand-alone library. This is available on CodePlex.
The library helps keep a stack of history that can be re-applied if the user elects to undo / redo. This could replace your private variables and also allow for multiple items in the undo history.
You can find documentation and downloads at http://muf.codeplex.com/