« first day (1006 days earlier)      last day (2174 days later) » 

5:00 AM
Have you read about "is-a" in the context of OOP?
 
Does it include or exclude the "|" character?
 
addOp "is-a" expression
 
addOp is a AddOpContext.
 
the pipe is an alternative - the expression rule has a couple of those
 
I've heard it and read it but haven't really "got it" yet
 
5:00 AM
| is the same as regex- it's a binary or.
 
literalExpression :
    numberLiteral
    | DATELITERAL
    | STRINGLITERAL
    | literalIdentifier typeHint?
;
^ that could be written as:
 
And a BinaryOR | is different from an ExclusiveOR XOR
 
literalExpression : numberLiteral  | DATELITERAL | STRINGLITERAL | literalIdentifier typeHint?;
 
There actually are several written like that - they're just easier to read vertically.
 
@Comintern What I was going to ask.
 
5:02 AM
Especially if there are a ton of them.
 
more maintenance-friendly too, if you want to add a #subType
 
Ok
 
One thing to keep in mind about ANTLR (and C#) is that unlike VBA, new-lines are just like any other whitespace.
 
which is why in C# you use ; to denote the end of a line?
 
5:04 AM
of an instruction
 
Technically end of statement
^^
 
;-)
in Antlr it terminates a rule
 
Ok
 
; in C style languages is the equivalent to a newline in VBA for all intents and purposes.
 
5:06 AM
Or :...
 
All this spoonfeeding is making eating this stuff a lot easier.
 
:)
so, we "build" the grammar - Antlr processes it and generates a number of C# source files for us
 
Which are those files?
 
one of them is VBALexer.cs; I think I only ever opened that one by accident
another is VBAParser.cs
one interesting thing to know is that all ParserRuleContext classes are nested types declared inside VBAParser
so the StartRuleContext looks like this:
 
_serializedATN sweet googalie moogalie... Glad you didn't have to type that.
 
5:08 AM
	public partial class StartRuleContext : ParserRuleContext {
		public ITerminalNode Eof() { return GetToken(VBAParser.Eof, 0); }
		public ModuleContext module() {
			return GetRuleContext<ModuleContext>(0);
		}
 
@Mat'sMug This is the limit of my current knowledge.
 
startRule : module EOF;
 
@Mat'sMug Beautiful formatting, no?
 
not bad for generated code
 
...if you like Java.
 
5:10 AM
Antlr has a heavy Java background
 
The code generation is done in Java.
 
Roslyn makes heavy use of generated code, and it is nicer :)
 
it's written by C#ers
 
Roslyn isn't written in Java.
 
5:11 AM
Oh, that's right--Java people like their braces all funny like that.
 
If it was, it would break every 6 months or so.
 
@Mat'sMug <access modifier> <Something I Don't Know> class <ClassName> : <Inherits From> {<Don't understand this part, at all>}
 
every parser rule becomes a partial class nested inside the generated VBAParser class, and derived from ParserRuleContext (an Antlr runtime type)
 
I've no experience with Partial | Abstract class stuff
 
partial classes are awesome - Antlr generating partial classes means we can extend their definition in another code file...
 
5:13 AM
A Partial class is one that can be split into several files.
That means you can add additional functionality to it.
 
...and make them, say, implement interfaces we'd like them to implement
 
An Abstract class is one that has to be inherited by a concrete class.
For example, if Animal is an abstract class, you might have Cat and Dog classes that inherit from it as a base class.
 
@Comintern public class Cat : Animal or public class Dog : Animal
 
yep
 
You can create a new Dog or Cat object, but you can't create a new Animal - it doesn't make sense - it's just an abstraction of the commonalities between cats and dogs.
 
5:16 AM
That I get the theory of. Still am not very comfortable with it in usage.
The idea of partial class still eludes me.
 
it's just a class that can be defined across multiple files
 
All partial class means is that I can add whatever I want to it.
 
it was all the rage when C# 2.0 introduced them
 
UserForms in VBA are kind of like partial classes.
 
so rather than public class Cat : Animal you'd have
 
5:17 AM
forms in WinForms (.net) are partial classes
 
^
You would have a partial Cat.
 
public class Cat : Feline, Mamalia , Animalia ?
 
that's the catch: there can be only one
 
where you're pulling parts from Feline, Mamalia, and Animalia to constitute a complete Cat?
 
otherwise it's multiple inheritance and compilers don't like that
 
5:18 AM
If the existing Cat implementation was missing a Meow() method, you could just add it in your own code and it would become part of the compiled class.
 
@Mat'sMug So pretty much Highlander style?
 
exactly
so abstract class Animalia, class Mamalia : Animalia, class Feline : Mamalia and class Cat : Feline
 
I would love multiple inheritance in C#.
but...
Multiple inheritance is a feature of some object-oriented computer programming languages in which an object or class can inherit characteristics and features from more than one parent object or parent class. It is distinct from single inheritance, where an object or class may only inherit from one particular object or class. Multiple inheritance has been a sensitive issue for many years, with opponents pointing to its increased complexity and ambiguity in situations such as the "diamond problem", where it may be ambiguous as to which parent class a particular feature is inherited from if more than...
 
the diamond problem
 
^ bingo.
 
5:20 AM
Again the idea of it I get. I just lack the experience to see it in use.
 
that's fine
 
Partial classes sidestep that by allowing you to "tack-on" functionality without multiple inheritance.
It's not quite the same, but it solves some of the same problems.
 
Bear with the following psuedocode
 
	public partial class StartRuleContext : ParserRuleContext {
		public ITerminalNode Eof() { return GetToken(VBAParser.Eof, 0); }
		public ModuleContext module() {
			return GetRuleContext<ModuleContext>(0);
		}
bring up the object browser and lookup ParserRuleContext
you'll find all the members StartRuleContext inherits
 
public class Human, class Walk : SomeWalkingClass, class Talk : SomeTalkingClass, class Think : NopeNotDoingIt
 
5:23 AM
in C# any class can inherit any other. unless it's sealed. sealed classes cannot be inherited
 
...safely...without reflection...
 
shhh
 
@Mat'sMug Sealed = Gandalf vs Balrog?
 
lol
Sealed just means you can't inherit from it.
 
public sealed class YouShallNotInheritMe
 
5:24 AM
@Mat'sMug That's what I was thinking
 
Usually it's because the sealed class wraps something that it doesn't want you to extend.
 
and then class Foobar : YouShallNotInheritMe won't compile
 
Until someone writes something that edits the emitted IL and can write that.
Or whatever.
 
so back to StartRuleContext, you can see it has a module() method that returns a ModuleContext
 
@Mat'sMug Antlr4.Runtime.ParserRuleContext : Antlr4.Runtime.RuleContext is what you were referring to?
 
5:26 AM
yep
then take a peek at Antlr4.Runtime.IToken
there's a Text property
a Line property
and a Column property
 
Channel, Column, Inputstream, ... , Type
 
yeah
 
I can see that. Superficially I understand that they are members that are supplied to ParserRuleContext through inheritance
 
TokenIndex is the position of the token in the input stream (it all started with a string containing a module's code, right?)
every token knows its position in the token stream, and in the source string
Rubberduck uses token positions to locate everything
that's one crucial point
 
When it doesn't, the wheels come off.
 
5:30 AM
So the Token = composed of ParseThings = composed of LexerThings
 
a token comes from a lexer rule; lexer rules can be made of other lexer rules; then parser rules are made from lexer rules and other parser rules
 
ParseThings are composed of LexerThings which implement Token interfaces.
 
SmallThing becomes part of LittleBiggerThing becomes part of MediumThing becomes part of LargeThing becomes part of RD. To find out where a SmallThing is locate you use the IToken.TokenIndex?
 
tokens' line and column properties tell us where they are in the module
...but only because we gave the parse the whole module
oh dear god
 
5:33 AM
He has to wash the walls down now. Nothing else is sticking to the walls since there's too much sausage up there already.
 
Is the random eyeball staring back at you yet?
 
@Comintern if we know method DoSomething has been modified, and we use the VBIDE API to get its start line S, then we can offset/prepend that string (the DoSomething member) with S empty lines, parse that, and bingo we've only parsed a single procedure and we haven't broken the token positions!!!!
is that not possible? what am I missing? I must be missing something, it can't be that simple, can it?
 
Yeah, that's possible.
The problem is tracking the offsets.
Do the positions update themselves if you use a stream re-writer?
 
yes
uh
yeah they have to
in the rewriter I mean
 
We should be using that for code re-writing then. Always.
 
5:37 AM
^
 
That way we wouldn't have to reparse after refactoring.
 
Has your RubberDucking explanation to me made you find an epiphany?
 
and you can dump the rewriter into the code module in one call
@IvenBach yes
 
Yep.
Which makes undo exactly like the indenter.
 
that's huge
 
5:39 AM
My job here is done then Yep dusts off hands I do good work.
 
lol
not kidding, I'm going to have to get to bed soon
 
Sorry I just have a bit of a dry sense of humor.
 
@Future, I think you could probably link tokens to text segments in AvalonEdit.
 
wipes tears
 
Some user named "Future" just got a random ping there...
 
5:40 AM
lol
moderator power-ping gets no match for @Future, you're good
 
@Mat'sMug So that pretty much concludes todays lesson?
 
Take that a step further though. If an inspection is attached to a context, the quickfix would be to rewrite itself.
 
@IvenBach the next step is to look at how RD calls the Antlr-generated code and consumes the parse trees
@Comintern that's ...crazy
 
And trust me, that is not an appetizing meal.
 
Ok.
 
5:43 AM
eh, it's just rewriting, what, half of Rubberduck?
 
Nah, maybe a third.
tops.
 
so about 80K lines of code then
 
@Comintern you can do that by tomorrow 7am?
 
#ThisLooksLikeAJobFor
 
I'm on it.
 
5:44 AM
lol
 
I make no promises as to whether it will compile.
2
 
I'm going to sleep on it
 
^
I need to hit the sack too.
 
'night!
 
Thanks for the walkthrough so far. I should be able to make time for more tomorrow.
 
5:47 AM
@IvenBach if you want to further explore stuff, you'll want to look at the Parse method of VBAModuleParser.cs
    public IParseTree Parse(string moduleName, string moduleCode, IParseTreeListener[] listeners, BaseErrorListener errorListener, out ITokenStream outStream)
    {
        var stream = new AntlrInputStream(moduleCode);
        var lexer = new VBALexer(stream);
        var tokens = new CommonTokenStream(lexer);
        var parser = new VBAParser(tokens);
        parser.AddErrorListener(errorListener);
        ParserRuleContext tree;
        try
        {
            parser.Interpreter.PredictionMode = PredictionMode.Sll;
the string goes to the input stream, the stream to the lexer; the lexer goes to the token stream, the token stream goes to the parser, and the parser gives us the parse tree
there's a song we sing in French over here about a little bird that's in an egg that's in a nest that's in a knot that's in a hole that's in a branch that's in a tree.. anyway
'night!
 
Does RD have any visualization of this information for documentation?
 
not really
 
That's what I was expecting.
 
anyway, 'night!
 
To examine it I just need to F9 and then run with debug attached?
 
5:52 AM
oh, the tree? yeah you can break and literally browse the parse tree in the debugger
(via each node's [children] property)
 
Ok. trying to do that right now. Thanks for the handholding so far
 
pleasure :)
 
I got stuck on `var existing = Target[name];` again. Couldn't get past it.
private void DeleteExistingCommandBar(string name)
{
try
{
var existing = Target[name];
if (existing != null)
{
existing.Delete();
Marshal.FinalReleaseComObject(existing);
}
}
catch
{
// specified commandbar didn't exist
}
}
 
6:15 AM
Argument Exception was Unhandled
 
 
2 hours later…
 
2 hours later…
11:05 AM
I will give @IvenBach credit to provide a pathway of Rubberduck orientation or initiation. youtube.com/watch?v=EJnXIqXI8X8
It's an insight understanding the gears and clock works of the Antrl in depth.
Thanks for that.
I've converted my religion into VS2017. :)
just difference in User Interface and little performance now and there within VS, otherwise. Doing some tests with RD once Nuget objects are loaded correctly.
I do believe as @FreeMan suggested earlier some materials from these range of conversations becomes improved wiki content later not limited to the RD tutorials.
 
11:56 AM
0
Q: Smallish VBA Macro runs really Slow

MinMortsMy Macro that I wrote is running really slowly and I'm not sure why. The Macro deletes the area, then reproduces one column of locations as a row, deleting any duplicates, then copy's across a column of dates, then puts the corresponding Mean value for each date under the correct functional locat...

 
12:47 PM
@IvenBach I would like to add two pieces of information regarding the lexer and parser rules:
First, the only difference between fragment rules and token rules is that fragments will never be returned as tokens. In our grammer this prevents sinlge letters to be returned as tokens, which the parser would not understand. You actually do not need to use fragments in the token rules; you could use string literals instead. We just use fragments because VBA is case-insensitive.
Second, whenever you have ambiguous lexer or parser rules, i.e. multiple rules can match the input, the topmost rule in
@Hosch250 I am already looking into running the inspection on selected modules only. That is why I proposed to provide an IDataForInspections inteface to the inspections instead of the state. Then one implementation could provide only the declarations on the selected modules.
Anyway, we have to get an IInspector into the `ParseCoordinator first to actually have a possibility to provide a reasonable module selection to the inpections.
 
1:49 PM
@puzzlepiece87 I would like to point out the two main reasons I prefer to work with classes than with standard modules. One is less coupled to the OOP design idea (ease of encapsulation) and one is what makes OOP work (flexibility through interfaces).
I think you already agree that having one huge procedure that does a lot of things hurts maintainability and readability. So, you break down your procedure into smaller pieced and those again into smaller pieces and repeat that until you reach something coming close to the single responsibility principle. One thing you will typically notice is
 
2:04 PM
@puzzlepiece87 Regarding interfaces I would like to add a nuance that is not conveyed that well by last night's old example of `ICar` by @ThunderFrame. An interface is not about being something but rather about behaving like something.
If you have an interface `ISaw` with a function `CutWood` taking wood and returning pieces of wood. It would be very reasonable for an `Axe` class to implement that interface. (The interface should better be named `IWoodCutter`.)
On the other side there is the very old example that a square should not implement `IRectangle` because it does not behave like one
 
2:16 PM
> Do we really have to reparse whenever a module gets removed or can we defer that? Which functionallity requires the reparse?

The problem here seems to be that the timing is wrong: when we trigger the reparse from the event handler we are in a race with the VBE. Since the handler is executed prior to the actual release of the component by the VBE, the VBE only gets the oportunity to release the component when the parsing run starts (on a background thread). The first thing done in the parsin
> @MDoerner if we don't sync right away, then the code explorer will contain modules (and associated navigation commands) that no longer exist.
 
2:57 PM
> @retailcoder The problem is: we are too fast. When the reparse queries the components from the VBE, the VBE has not gotten around to actually release the component.

With a sufficiently large test project, I can repro the exception now.
> @MDoerner - I can see what I can do to delay raising the managed event until the VBE is actually finished removing it from the components collection. There may be a windows event associated with it, but I'd need to check. I'd prefer not to do anything that would block if I can avoid it (i.e. looping until the module count decreases) - this will all be running on the VBE's main thread.
 
3:13 PM
Hm, cannot repro #2813 anymore.
Probably, something got corrupted in something I did before adding the modules.
 
Hm, it's actually the CodePane. I edited the issue.
 
3:34 PM
> Does the initial parse run? I can't reproduce this issue.
> This seems to be a timing issue. The failing code is in `CodePane`:
```
public IWindow Window
{
get { return new Window(IsWrappingNullReference ? null : Target.Window); }
}
```
Exception info:
```
System.Runtime.InteropServices.COMException was unhandled
_HResult=-2147352560
_message=Invalid callee. (Exception from HRESULT: 0x80020010 (DISP_E_BADCALLEE))
HResult=-2147352560
IsTransient=false
Message=Invalid callee. (Exception from HR
 
As a very simplistic hack to circumvent #2773 for the moment, I added a delay to ParseAllInternal in the ParseCoordinator, which runs on a background thread.
Problem is, we always get the delay.
 
hmm, how much of a delay is it?
 
I think what's happening on #2814 is that the VBE is activating the window right before it destroys it. When it activates, it sets the cursor in the code pane, and then RD is catching that event with a (now-destroyed) hWnd. With luck, it should be a matter of just adding a call to IsWindow before calling GetCodePaneFromHwnd.
 
I tested with 0.5s.
 
if it works with half that delay then it could be reasonable to keep around
 
3:43 PM
Now, testing with 0.2s.
 
0.1s is instant as far as UX is concerned
might not be enough though
 
We have a delay anyway because there is some processing before setting the states to pending.
 
yeah
 
However, we have to do the processing first. Otherwise we set states of things that should no longer be there.
Maybe, we could set the overall state to Pending, but touch the modules only when the processing is done.
 
the dual-purpose of ParserState enum is starting to annoy me lol it's really ParserState and then ModuleState
not that it would solve anything, but eh
 
3:54 PM
I think another status like Initiating, which does not allow clicking the button, would be a good idea. This would tell the user that the request is being processed and at the same time prevent him to request another parse by clicking again during teh wind up.
OK, 50ms still do the trick on my machine.
 
@M.Doerner agreed, but only if you make that Initialising ;-)
 
Non-native speaker, hurray!
I will open an issue, so we do not forget.
 
eh, I noticed a typo in the French translation for the parser states... I need to fix that before next release too
 
> Should be "Résolution". Easy fix - the hard part is not forgetting about it... hence this issue.
> At the moment, at the start of every parsing run the status of all modules is set to `Pending`, which still allows clicking the refresh button and requesting yet anothe parsing run.
Moreover, on the initial parse this introduces a (further) delay between the button click and the state changeing. (This is in case the initial parse did not get triggered automatically)

I might be a good idea to introduce a new state, maybe called `Initialising`. This state should deactivate the refresh button
 
Homework question. I'm reading: rubberduckvba.wordpress.com/2016/06/16/…
"This means code that doesn’t directly depend on MsgBox, or any given specific Worksheet or UserForm."
 
4:09 PM
yeah?
 
While hopefully not way overapplying that line, does that mean if I use a Userform for a program, and if I move a code module to another workbook but not the Userform and it breaks, did I program it poorly? Does it "directly depend" on the Userform? If so, what's the fix?
I will also assume that an example of "directly depending on Msgbox" would be to show the user specific data that they have no other way of accessing afterwards besides memory or writing it down? If so, I understand the fix and that's a good point.
 
the point about MsgBox (or any dependency) is that you want to be able to run automated tests that exercise your code; if your code spawns MsgBox and brings up userforms, the test can't be automated - you have to click buttons manually.
so instead you depend on an interface that "wraps" the MsgBox, and so your test code can execute the procedure and provide it with a "fake" implementation that doesn't bring up an actual MsgBox
    Option Explicit
    Implements IMsgBox
    Private result As VbMsgBoxResult

    Public Property Get MsgBoxResult() As VbMsgBoxResult
        MsgBoxResult = result
    End Property

    Public Property Let MsgBoxResult(ByVal value As VbMsgBoxResult)
        result = value
    End Property

    Public Function Show(ByVal message As String, ByVal title As String, Optional ByVal style As VbMsgBoxStyle) As VbMsgBoxResult
        Show = result
    End Function
 
> Added tests to DeclarationFinderTests.cs for function GetDeclarationsAccessibleToScope(...) - #2800.
Removes equivalent (and now, unused) logic from AssignedByValParameter...QuickFix.cs
Removes redundant declaration accessibility tests from RenameTests.cs and AssignedByValParameter...QuickFixTests.cs.

Collateral damage/edit: Adds *.playlist to gitignore to ignore VS Test Explorer playlist files.
 
say you have an IMsgBox interface that looks like this:
Public Function Show(ByVal message As String, ByVal title As String, Optional ByVal style As VbMsgBoxStyle) As VbMsgBoxResult
End Function
the "fake" implementation is above
the "real" implementation could be:
    Option Explicit
    Implements IMsgBox

    Public Function Show(ByVal message As String, ByVal title As String, Optional ByVal style As VbMsgBoxStyle) As VbMsgBoxResult
        MsgBox message, title, style
    End Function
and so instead of depending on the VBA.Interaction.MsgBox function directly, your code depends on that IMsgBox interface
 
[rubberduck-vba/Rubberduck] build for commit b1a1c2da on unknown branch: AppVeyor build succeeded
 
4:24 PM
the caller "injects" the LiveMsgBox, so IMsgBox.Show calls end up showing an actual MsgBox that the user can click buttons on, but the tests "inject" the FakeMsgBox, and can simulate what happens when the user clicks Ok or Cancel
and that's something you absolutely cannot do without classes
The VBA tag is scaring me here. — Mat's Mug 8 secs ago
 
4:44 PM
@M.Doerner That's a helpful bit of knowledge.
 
indeed :)
 
4:59 PM
@Mat'sMug any idea why my VS debug is still hanging?
 
quite possibly because the attached EXCEL.EXE process didn't terminate [properly] - just hit the "stop" button
 
I should rephrase my question. Why when I was trying to step through VS it wouldn't proceed past the instruction var existing = Target[name];. It was the same issue that I was having previously.
 
what type is Target?
looks like that code is assuming the Target dictionary has a key for name, and it appears this assumption is wrong
try
 
It's in the DeleteCommandBar section IIRC.
 
Declaration existing; // assuming existing is a declaration instance
Target.TryGetValue(name, out existing);
if (existing != null)
{
    // ...
}
 
5:07 PM
I'll be able to check at home after work.
 
5:20 PM
> Running Version 2.0.9
In a empty database, newly created,
I create a new module & insert the following
```
Function Main()
Debug.Print "Foo bar"
' BUG: This is a Bug
End Function
```
I open the ToDo explorer, hit the refresh button, and nothing happens.

So upgraded to Version 2.0.12
Now all the functions are grayed out from the menu, except settings...

Thanks
Larry
 
@Mat'sMug Thank you very much for that explanation, that not only helped me understand how not to be dependent on msgboxs, userforms, etc. but also helped me understand the advantages of classes.
 
> There's a bit of a race condition at startup - the initial parse will sometimes happen automatically, but not systematically. See README.md, #2728, or Stack Overflow.
> Does the TODO explorer refresh correctly after the initial parse completes?
> I cannot repro this anymore. Probably, RD was in a bad state after encountering issue #2773.
 
5:50 PM
> This introduces a hack to circumvent the cause of issue #2773.

In `ParseAllInternal`, which is only called in the live code, I added a delay of 50ms before refreshing the projects from the VBE so that the VBE has time to actually release components before we query it, in case the parse is requested from the handler for the component removed event.
[rubberduck-vba/Rubberduck] build for commit ff42e3f4 on unknown branch: AppVeyor build succeeded
 
6:20 PM
> Closes #2814

This is a temporary fix pending some better method of matching an `hWnd` to a `CodePane` than testing all of the captions in the CodePanes collection. Not sure if the VBE recycles all of the windows when it removes one, but if so we should be able to get a hook in there and manually track the window associations.
[rubberduck-vba/Rubberduck] build for commit e9fb7ca8 on unknown branch: AppVeyor build succeeded
[rubberduck-vba/Rubberduck] build for commit b43d1a6e on unknown branch: AppVeyor build succeeded
[rubberduck-vba/Rubberduck] build for commit e9050d8e on unknown branch: AppVeyor build succeeded
 
^ What do we do to support that? Hit the "delete example" button?
downvote?
Oh never mind, you're asking us to hit "Dismiss" on the Improvements Requested box?
 
@Mat'sMug Dismissed.
 
@Gareth - missed your comments in a few thousand messages. Sorry to hear about your recent times. You're welcome back in whatever capacity you'd like.
 
[rubberduck-vba/Rubberduck] comintern pushed commit e9fb7ca8 to next: Validate handles and catch COM errors when matching windows to code panes. Closes #2814
[rubberduck-vba/Rubberduck] web-flow pushed commit 5dd8a2d6 to next: Merge branch 'next' into next
[retailcoder/Rubberduck] MDoerner pushed commit 57098fbf to rd-next: Hack for issue #2773
[rubberduck-vba/Rubberduck] build for commit 45d91c82 on next: AppVeyor build succeeded
[rubberduck-vba/Rubberduck] build for commit 019351a1 on unknown branch: AppVeyor build succeeded
 
@M.Doerner This is the final piece of me understanding, particularly this passage: "You can write a function for each way to do it. However, if you decide to use another way, you either have to replace the old procedure or modify every caller to use the new procedure."
I didn't think it would be that big of a deal, just add parameters to the function to compensate, but you are right, then you have to go back and modify every caller. For a class you can request just one or more properties without having to request every property you may add later.
That was a huge help, thank you @M.Doerner
I finally feel comfortable with these and am going to start converting my God macros to classes.
 
9:46 PM
@Comintern so I just merged the latest changes... Double-clicked a node in the code explorer and got a BSOD
 
WTF?
 
Waiting for reboot... Anywhere you'd want me to look?
 
@Mat'sMug It's like @Comintern says: "Just remember - there's no shame in end-task. Hard crashes are a badge of honor. Save your work..."
Clearly you just took that up to 11
 
lol
Hopefully that was just a coincidence.. Or a cosmic ray or something
 
@Mat'sMug Not entirely sure. I didn't think you could do that in managed code...
 
9:48 PM
By which he means, "Do it again! Do it again!"
 
LOL
 
That was in the RD Code Explorer, not the VBE Project Window?
 
Yeah RD CE
 
Think the only thing in there is the set focus call.
 
eventvwr loading
 
9:52 PM
My money is on nothing logged there.
 
Kernel-Power critical entry, but nothing useful
 
That the one warning that you've spooled the CPU at > 99% for too long?
 
Starting Excel
Loading VBE/RD
lol, parser error, can't access file
%temp%\Rubberduck is empty
 
WTF?
 
The msgbox looked like a vba msgbox
 
9:59 PM
Yeah, that's because we're calling a VBE function to export.
 
Logs have a comexception in vbcomponent.get_codemodule
 

« first day (1006 days earlier)      last day (2174 days later) »