
Mike_R
Avatar/Signature-
Posts
316 -
Joined
-
Last visited
Mike_R's Achievements
Newbie (1/14)
0
Reputation
-
True, you don't need 'ByRef' here, since you aren't changing the instance, so, yes, 'ByVal' makes more sense. But this isn't your problem (as you said). I have no clue, I'm afraid... Are you saying that the 'doc As Word.Document' parameter is coming through as 'Nothing' even though the argument passed in is non-null?? Can you show your code, including your logging calls for your LoadDoc method?
-
I'm not a Word programmer, but your code looks ok to me. I think you'll have to trace this with debugging tools. Trace the actual assignment of '_document = doc' to make sure this is getting set right. (It must, but, well, trace it anyway...) Then put have a breakpoint within the method that gets called when you click a toolbar button. Then trace/step into that code as well to see what is going on. - Mike
-
I'm glad it helped (at least a little). You might want to try something like: oGraph.Application.DataSheet.Range("A1:C3").Value And see if you can get a 2D array of values or set a 2D array of values in one shot. It will either work or you'll get an exception, but it couldn't hurt to try, right?
-
Hey John, I'm sorry to say, but I do not have a clue about the PowerPoint object model. Using the PowerPoint object browser in VBA, I cannot even find the Application.DataSheet member. Odd... The examples I see online seem to use the same "cell-by-cell" approach that you are using. (For example: here. However, there seems to be a mechanism for importing an Excel spreadsheet into a chart, so that might be the way to go, if you can figure it out. Sorry I can't help more, but I'm not a PowerPoint guy...
-
Sure, no problem, glad it helped! :), Mike
-
Re: A demonstration Yeah, I think you got it. And, and unfortunately, this would be a reverse-compatibility issue if they changed it. However, one could envision a world where the '+' operator is overloaded for 'byte' and 'short', in that case: byte b = 250; b = b + b; would return 244 (or throw an exception if checked), instead of returning 500. If you wanted to get the behavior shown in your 'short s = (short) (b + b);' example then one would have to explicitly cast at least one of the operands: byte b = 250; short s = (short)b + b; I really think that this is the way it "should" be, the more I think about it... but there would be reverse-compatibility issues if they did this now, as highlighted by your example. My guess as to why they do it this way is that this would take *extra* steps to execute overflow behavior for 8 bits or 16 bit types, which wouldn't overflow when using native 32 bit arithmetic. Still, the "explicit cast approach" would allow one to force 32 bit calculations -- but it would take extra coding (an explicit cast) to force the more efficient execution. This brings up something related though... How does the following execute on a 64 bit machine? int i = int.MaxValue; long l = i + i; I don't have access to a 64 bit machine, but I'll guess that it would have to assign -2 to the 'long l' value, right? Otherwise there would be massive compatibility issues depending on whether the code is running on a 32 bit or 64 bit machine. But this would also mean that an "artificial overflow" concept (extra code checks) would be in force here for 'int + int', but not for 'byte + byte' or 'short + short'. Kind of interesting...
-
Re: Compiler evaluation Ok, fair enough... But 'b + b' is a compile time error, not a run-time error, so this still leaves us with the fact that '++' and '+=' appear to be explicitly overloaded for 'byte' and 'short' whereas '+' upcasts to integer instead, but then you get snagged when assigning the return value.
-
Re: Option Strict On Actually, while we're on the subject... how is it that the following is legal in C# without an explicit cast: byte b = 0; b = 1; Or this: byte b = 0; b = 1 + 1; But not this: byte b = 0; b = b + b; // <-- Compile time error. Kinda weird, eh? Seems to be some compiler "help" in some circumstances, but not in others. I'm wondering what the rule is here. (Is there a rule?)
-
Re: Option Strict On Well, VB.NET is trying to be helpful when in 'Option Strict Off' here, and I think that it is. In most other cases, though, you really do want to be forced to make your casts explicit, so 'Option Strict On' really is pretty much a necessity. The same thing happens in C#, although not with the '+=' or '++' operator. The problem is that the '+' operator is defined for integer, but not for byte or short, so byte and short operands are upcasted to integer, added together, and then returned as an integer. So when returning the result back to the byte it needs to be explicitly cast back: On the other hand, the '++' and '+=' operators are overloaded to accept and return byte: byte b = 0; b++; // <-- Ok b += 1; // <-- Ok b = b + b; // <-- Compile time error! The compiler's complaint on the last line is: "Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)" And so we're required to use: b = (byte)(b + b); I don't see why the '+' operator could not be overloaded in a future version in order to directly handle byte and short data types (instead of upcasting). It would seem to make more sense that '+' operate by the same rules as '+=' and '++'. I guess the problem with trying to change this the issue of overflow, esp. when we could have two flavors: unchecked or checked. Still, I think it's an uncomfortable situation that '++' and '+=' are operating differently, allowing implicit casts whereas '+' does not.
-
Ok, thanks PD for clearing that up. :-) Funny, I had thought it was the other way around: that the CLR would not be taking extra steps like this and that VB.NET was "injecting code" to zero it out. Funny, then, that C# does not enforce field initializers? It would seem much easier to enforce that a field is initialized at the point of declaration (or within all constructors) than the complex path analysis that C# must undergo for variables? C# seems to be saying that it's ok to assume that a field will be the default null/0/false but it's not ok to assume the same for a variable? Anyway, thanks for solving this mystery for me, PD. One less thing keeping me up at night... :)
-
I was thinking about how VB.NET auto-initializes its variables if not explicitly written to before being read, something that C# does not allow. The simplest example would be something like this: ' VB.NET: Public Sub MySub() Dim j As Integer MessageBox.Show(j.ToString) End Sub The equivalent in C# would not compile: // C#: public void MySub() { int j; MessageBox.Show(j.ToString()); } The compiler would complain about "Use of unassigned local variable 'j'" at the point where 'j.ToString()' is called. So I wondered what the VB.NET code would look like when viewing the IL. I had expected to find an explicit assignment of 'j' to 0, presumably created by the VB.NET compiler. But I was surprised at what I found: .method public instance void MySub() cil managed { .maxstack 1 .locals init ( [0] int32 j) L_0000: ldloca.s j L_0002: call instance string [mscorlib]System.Int32::ToString() L_0007: call valuetype [system.Windows.Forms]System.Windows.Forms .DialogResult [system.Windows.Forms]System.Windows.Forms .MessageBox::Show(string) L_000c: pop L_000d: ret } Basically, the 'int32 j' is not assigned a value before .ToString() is called. I had expected to see 'j' being set to zero via a 'ldc.i4.0' call followed by 'stloc.0' and then the rest of the routine would proceed as shown above. That is, I had expected to see this: .method public instance void MySub() cil managed { .maxstack 1 .locals init ( [0] int32 j) L_0000: ldc.i4.0 L_0001: stloc.0 L_0002: ldloca.s j L_0003: call instance string [mscorlib]System.Int32::ToString() L_0004: call valuetype [system.Windows.Forms]System.Windows.Forms .DialogResult [system.Windows.Forms]System.Windows.Forms .MessageBox::Show(string) L_0005: pop L_0006: ret } So does the CLR itself zero out all variables? And therefore VB.NET is not really "doing anything", but instead is merely allowing the default behavior to occur, whereas C# is being more restrictive? Or is there a CIL setting, attribute, or the like somewhere that determines whether unassigned memory should be zeroed out before use automatically? (A setting that VB.NET would be using, but not C#?) Anyway, I was wondering if anyone here knew what was going on... Mike
-
You could also try the 'Microsoft.VisualBasic.Strings.Split' method, which can also handle a multi-character string splitter. It might handle your "last character" issue better, don't know... I think it's also a little safer to use in general than RegEx.Split(), unless you really do wish to split on a pattern. In your case you are passing in Cr & Lf, so it's fine, but if you passed in "\d", for example, all heck would break loose, splitting on every digit... You know the source in this case, so it's ok, but if you don't know what the spit value will be beforehand (supplied by the user, perhaps?) then you could get really snagged with RegEx.Split, I think.
-
Ah, thank you mskeel! Using #if DEBUG ... #endif blocks will definitely be the way to go for me. I did not realize that the #if directive could be used to surround an entire class. This is beautiful and does exactly what I need. (I had thought that it could only be used within a method.) Maybe, I'm not quite decided on this yet. I am just taking around the idea at this point. But I think that it makes a lot of sense at a lot of levels... I have no real problems with NUnit or the like. But, yes, the main idea I'm shooting for here is to have the testing code be as physically close to the implementation as possible. It makes it easier to make and test, and it makes everything more portable: if I copy and paste, or re-factor and move the class, the test code moves right with the class that is being tested. Since NUnit works using reflection, keying on various attributes, I wonder if I might be able to simply use NUnit and still use internal, nested testing classes. I've not tested this though -- since NUnit uses reflection, a public class should not be required here, but it is possible that it still respects public vs private/internal and only executes public classes that have the correct attributes? But I don't know... Also since NUnit's methods are also void methods, without any out parameters, if this works then I could simply use a [Conditional("DEBUG")] attribute for each method in the class in this case. However, your idea to use #if ..#endif blocks to surround the entire class and more effective. Anyway, just thinking out loud at the moment, I guess... Mike
-
I have nothing against NUnit or the like, I think that these unit-testing programs really are excellent... But more and more it's been bothering me that the testing code is separate from the class that is being testing. So I decided to put my testing code for each class within an internal, nested class named "Tester", nested within the class being tested. I then use the assembly:InternalsVisibleToAttribute to enable my testing assembly -- and only my testing assembly -- to have access to this testing code. So far, so good... However, for my last step, I would like to prevent this testing code from being emitted to CIL when compiled as a release build. My first thought was to use the [Conditional("DEBUG")] attribute, however, the ConditionalAttribute cannot be used with methods that have a non-void return value, nor with methods that have out parameters. :( Using partial methods would be extremely awkward, and would suffer from the same problem... My only other thought is to use the [Conditional("DEBUG")] attribute using void methods and return my results to a static global field. Since all my testing is single threaded anyway, this would work fine... But it does feel pretty crude. :( Does anyone have any other ideas? Is there any other way to suppress a method from being compiled to the CIL? Thanks guys, in advance... Mike
-
I have no solutions for you... However, I think that a related question is: how do you guarantee that there is a single, unique solution? That is, the starting position for your board should fill in enough squares so that there is only one possible solution without filling in too many, or else the problem will be to easily solved. If the starting position does not guarantee a single, unique solution, then your "hint" functionality becomes much more complicated! I suppose that your hint could show any one of several valid values, or perhaps show them all? Ideally, however, you're starting board should only allow for one possible solution... If that is the case, then your hint functionality will be easier to implement. Unfortunately my thoughts here are not of much help! You need some sort of solution algorithm, and that same algorithm would be used to determine if there is only one unique solution, as well as be used for your hint functionality... (I hope this helps in some small way? Probably not...)